Thread: copy constructor and return type problem

  1. #1
    Waxy-Dock
    Join Date
    Mar 2005
    Posts
    69

    calling iterator on vector <int> prob.

    hey,

    im returning a begin() and end() iterator for my vector<int> in respective methods(including constBegin/End(), for some reason when i try to use it(ie. in contains()), the compiler gives errors. Also my copy constuctor gives a compile error, i dont understand why it says "error: parse error before `.' token"??

    btw im new to c++ ...is that the correct way to use my copy constructor " IntSet newSet = a;"

    thanks for any help
    Code:
    using namespace std;
    
    typedef vector<int>::iterator setIterator;
    typedef vector<int>::const_iterator constSetIterator;
    
    IntSet::IntSet(void) {
    
    }
    
    IntSet::IntSet(const IntSet&) {
        
        for (setIterator it = IntSet.begin(); it!=IntSet.end(); ++it) {
            this->add(*it);
        }
    }
    
    /* prints the entire set in accending order */
    void IntSet::printSet(void)const {
         sort(constBegin(), constEnd());
         for (constSetIterator it = constBegin(); it!=constEnd(); ++it) {
            cout << *it << ", ";
         }
    }
    
    /* returns true if v is in the set */
    bool IntSet::contains(int v)const {
    
         for (constSetIterator it = constBegin(); it!=constEnd(); ++it) {
             if (v == *it)
                  return true;
         }
         return false;
    }
    
    /* returns a union of the sets a and b */
    IntSet operator+(IntSet a, IntSet b){
           IntSet newSet = a;
    
           for (constSetIterator it = b.begin(); it!=b.end(); ++it) {
               if (!newSet.contains(*it))
                  newSet.add(*it);
           }
           
           return newSet;
    }
    
    setIterator IntSet::begin(void) {
        return this->set.begin();
    }
    
    constSetIterator IntSet::constBegin(void) {
        return this->set.begin();
    }
    
    setIterator IntSet::end(void) {
        return this->set.end();
    }
    
    constSetIterator IntSet::constEnd(void) {
        return this->set.end();
    }
    the method headers for the begin/end methods are here
    Code:
    vector<int>::iterator begin(void);
                 vector<int>::const_iterator constBegin(void);
                 vector<int>::iterator end(void);
                 vector<int>::const_iterator constEnd(void);
    Last edited by waxydock; 04-29-2005 at 09:56 PM.

  2. #2
    Waxy-Dock
    Join Date
    Mar 2005
    Posts
    69
    i figured out the prob. with the end() and begin() methods but

    im still have problems with the copy constructor
    this is the error i get:

    IntSet.cc: In copy constructor `IntSet::IntSet(const IntSet&)':
    IntSet.cc:17: error: passing `const IntSet' as `this' argument of `
    __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >
    IntSet::begin()' discards qualifiers
    IntSet.cc:17: error: passing `const IntSet' as `this' argument of `
    __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >
    IntSet::end()' discards qualifiers

    Code:
    IntSet::IntSet(const IntSet &intset) {
        
        for (vector<int>::iterator it = intset.begin(); it!=intset.end(); ++it) {
            this->add(*it);
        }
    }
    and i use it here--is this the right way to use it
    Code:
    /* returns a union of the sets a and b */
    IntSet operator+(IntSet a, IntSet b){
           IntSet newSet = a;
    
           for (setIterator it = b.begin(); it!=b.end(); ++it) {
               if (!newSet.contains(*it))
                  newSet.add(*it);
           }
           
           return newSet;
    }
    here are the begin() and end() methods
    Code:
    setIterator IntSet::begin(void) {
        return set.begin();
    }
    
    setIterator IntSet::end(void) {
        return set.end();
    }
    Last edited by waxydock; 04-29-2005 at 10:38 PM.

  3. #3
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    btw im new to c++ ...is that the correct way to use my copy constructor " IntSet newSet = a;"
    I don't like that syntax: it's not clear that the copy constructor is being called. Instead, I like this syntax better:

    Intset newSet(a);

    and i use it here--is this the right way to use it
    Code:
    /* returns a union of the sets a and b */
    IntSet operator+(IntSet a, IntSet b){
           IntSet newSet = a;
    
           for (setIterator it = b.begin(); it!=b.end(); ++it) {
               if (!newSet.contains(*it))
                  newSet.add(*it);
           }
           
           return newSet;
    }
    Your operator+ function shouldn't need to change a or b. In your method, a or b can't be changed because you are passing-by-value, so the original objects are copied, and the copies are sent to the function. So, anything done to the copies in the function won't be reflected in the original objects. However, passing by value is inefficient. Therefore, to protect the original objects from being changed and to be more efficient, the parameters to the operator+ function should be const references:

    IntSet operator+(const IntSet& a, const IntSet& b)

    That reads: 'a' is a reference to a const IntSet. Putting const in front of a parameter tells the compiler to alert you if your function mistakenly tries to change the object. Making the parameter a reference causes the address of the object to be passed rather than a copy of the entire object.

    im still have problems with the copy constructor
    this is the error i get:

    IntSet.cc: In copy constructor `IntSet::IntSet(const IntSet&)':
    IntSet.cc:17: error: passing `const IntSet' as `this' argument of `
    __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >
    IntSet::begin()' discards qualifiers
    I think that has to do with the fact that your object 'intset':
    Code:
    IntSet::IntSet(const IntSet &intset) {
        
        for (vector<int>::iterator it = intset.begin(); it!=intset.end(); ++it) {
            this->add(*it);
        }
    }
    is a const object, and only const member functions can operate on const objects (const member functions make the this pointer a constant ensuring that the object can't be changed). Since begin() and end() are not const member functions, you get an error. Essentially, there is a risk that intset could be changed by begin() or end(), which means you cannot use a plain iterator on intset. You should try using a const_iterator instead.
    Last edited by 7stud; 04-30-2005 at 12:49 AM.

  4. #4
    Waxy-Dock
    Join Date
    Mar 2005
    Posts
    69
    im still getting the same error

    IntSet.cc: In copy constructor `IntSet::IntSet(const IntSet&)':
    IntSet.cc:17: error: passing `const IntSet' as `this' argument of `
    __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >
    IntSet::begin()' discards qualifiers
    IntSet.cc:17: error: passing `const IntSet' as `this' argument of `
    __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >
    IntSet::end()' discards qualifiers
    Code:
    typedef vector<int>::const_iterator constSetIterator;
    IntSet::IntSet(const IntSet &intset) {
    
        for (constSetIterator it = intset.begin(); it!=intset.end(); ++it) {
            this->add(*it);
        }
    }
    btw should i make the operator++ method const as well

    thanks

Popular pages Recent additions subscribe to a feed