GIDForums  

Go Back   GIDForums > Computer Programming Forums > CPP / C++ Forum
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 08-Sep-2007, 08:28
ktcm ktcm is offline
New Member
 
Join Date: Jul 2007
Posts: 15
ktcm is on a distinguished road

Vector of user defined type


I am having some trouble inserting elements in a vector of a user defined type. Does anyone know what could be the issue? The error message I get is
"error C2558: class 'Rock' : no copy constructor available or copy constructor is declared 'explicit'" Thanks for your help in advance! =)

CPP / C++ / C Code:
class Rock {
	double weight;
public:
	Rock (double wtSet):weight (wtSet){
		cout <<"Rock created\n";
	}
	Rock (Rock &rock){
		weight = rock.weight;
		cout <<"Rock copy\n";
	}
	Rock& operator = (Rock &rockOp){
		cout <<"Rock assigned";
		return rockOp;
	}
	~Rock (){
		cout <<"Rock destroyed\n";
	}
};

int _tmain(int argc, _TCHAR* argv[])
{
             Rock r1(1), r2(2);
	vector <Rock> rockV;
             rockV.push_back(r1);
}
</code>
  #2  
Old 08-Sep-2007, 08:41
davis
 
Posts: n/a

Re: Vector of user defined type


You haven't properly implemented your copy constructor (cctor).

CPP / C++ / C Code:
Rock::Rock( Rock const& rhs );

...is the signature. In your cctor "attempt," you are passing a Rock& not a const &.

Therefore, you have not defined a cctor, only an overloaded ctor.


:davis:
  #3  
Old 08-Sep-2007, 09:09
ktcm ktcm is offline
New Member
 
Join Date: Jul 2007
Posts: 15
ktcm is on a distinguished road

Re: Vector of user defined type


Hi, thanks for your help. Using a constant reference as a parameter, I get the message
error C2679: binary '=' : no operator found which takes a right-hand operand of type 'const Rock' (or there is no acceptable conversion)
I tried to const_cast the const away, but the compiler does not seem to allow it.
  #4  
Old 08-Sep-2007, 13:20
davis
 
Posts: n/a

Re: Vector of user defined type


Quote:
Originally Posted by ktcm
Hi, thanks for your help. Using a constant reference as a parameter, I get the message
error C2679: binary '=' : no operator found which takes a right-hand operand of type 'const Rock' (or there is no acceptable conversion)
I tried to const_cast the const away, but the compiler does not seem to allow it.

That's because the signature for an assignment operator also takes a const& and not a non-const reference. Maybe you should read up on const correctness? Imagine the idea of you doing something like:

CPP / C++ / C Code:
#include <iostream>

using namespace std;

int add( int& a, int& b )
{
    a = 14;
    b = 17;
    return a+b;
}

int main()
{
    int a = 5;
    int b = 7;

    int c = add( a, b );
    cout << c << " " << a << " " << b << endl;
    return 0;
}

The add operation has modified your values for a and b and returned something completely undesirable in c. In other words, had add taken a pair of const references for a and b, then we would know that it cannot/would not ever modify the values of a & b. In fact, we would have seen:

Code:
nonconst.cpp: In function 'int add(const int&, const int&)': nonconst.cpp:7: error: assignment of read-only reference 'a' nonconst.cpp:8: error: assignment of read-only reference 'b'

...errors when compiling.

However, in your own particular world, you decided that you would declare an operator that did not require a const&, so, since it is not the signature of the default assignment operator, your overridden operator applies. Using const_cast here is useless, because it is the container implicitly calling it, not your code directly.

Here is a good idea. Learn what the signatures are for your basic class operations. Here is a quick, abbreviated example:

CPP / C++ / C Code:
class Fraction
{
public:
    // default ctor
    Fraction();
    // overloaded ctor
    Fraction( const int numerator, const int denominator );
    // cctor
    Fraction( Fraction const& rhs );
    // dtor
    virtual ~Fraction();
    // assignment operator
    Fraction& operator=( Fraction const& rhs );
    // equality operator
    bool operator==( Fraction const& rhs ) const;
    // inequality operator
    bool operator!=( Fraction const& rhs ) const;
    // streaming output operator (aka "archiving" operator)
    friend std::ostream& operator<<( std::ostream& os, Fraction const& fraction );
    // streaming input operator (aka "archiving" operator)
    friend std::istream& operator>>( std::istream& is, Fraction& fraction );
protected:
private:
    int m_numerator;
    int m_denominator;
};

Of course, in a real "Fraction" class, we would also expect to find operator< and operator> implementations...



:davis:
  #5  
Old 08-Sep-2007, 14:02
davis
 
Posts: n/a

Re: Vector of user defined type


Quote:
Originally Posted by ktcm
Hi, thanks for your help. Using a constant reference as a parameter, I get the message
error C2679: binary '=' : no operator found which takes a right-hand operand of type 'const Rock' (or there is no acceptable conversion)
I tried to const_cast the const away, but the compiler does not seem to allow it.

Here is your Rock class more fully implemented:

CPP / C++ / C Code:
#include <iostream>
#include <iomanip>
#include <vector>

using namespace std;

class Rock
{
public:
    Rock( double weight ) : m_weight( weight ){}
    Rock( Rock const& rhs )
    {
        m_weight = rhs.m_weight;
    }
    virtual ~Rock(){}
    Rock& operator=( Rock const& rhs )
    {
        m_weight = rhs.m_weight;
        return *this;
    }
    bool operator==( Rock const& rhs )
    {
        bool isEquality = false;
        if( m_weight == rhs.m_weight )
        {
            isEquality = true;
        }
        return isEquality;
    }
    bool operator!=( Rock const& rhs )
    {
        return !(*this == rhs);
    }
    friend std::ostream& operator<<( std::ostream& os, Rock const& rhs )
    {
        os << rhs.m_weight;
        return os;
    }
    friend std::istream& operator>>( std::istream& is, Rock& rhs )
    {
        is >> rhs.m_weight;
        return is;
    }
    double getWeight() const
    {
        return m_weight;
    }
    void setWeight( const double weight )
    {
        m_weight = weight;
    }
private:
    double m_weight;
};

void spew_rocks( std::vector<Rock>& v )
{
    std::vector<Rock>::iterator it;
    for( it = v.begin(); it!= v.end(); it++ )
    {
        cout << (*it) << endl;
    }
}

int main()
{
    Rock r1( 1.01 );
    Rock r2( 2.02 );

     cout << setprecision( 6 ) << setiosflags( ios::fixed | ios::showpoint );

    std::vector<Rock>vRocks;
    vRocks.push_back( r1 );
    vRocks.push_back( r2 );

    spew_rocks( vRocks );

    if( r1 == r2 )
    {
        cout << "rocks 1 and 2 are equal" << endl;
    }

    if( r1 != r2 )
    {
        cout << "rocks 1 and 2 are not equal" << endl;
    }

    r1 = r2;
    if( r1 == r2 )
    {
        cout << "rocks 1 and 2 are equal" << endl;
    }

    vRocks.clear();
    r1.setWeight( 3.14 );

    cout << "Enter a new weight for rock 2: ";
    cin >> r2;

    vRocks.push_back( r1 );
    vRocks.push_back( r2 );

    spew_rocks( vRocks );

    return 0;
}

Output:

Code:
1.010000 2.020000 rocks 1 and 2 are not equal rocks 1 and 2 are equal Enter a new weight for rock 2: 2.975 3.140000 2.975000

...of course, there is nothing to stop the user from entering a negative weight for a rock, but that's one of the interesting aspects of producing real-world code that you'll eventually come across...and have to deal with effectively!


:davis:
  #6  
Old 09-Sep-2007, 07:57
ktcm ktcm is offline
New Member
 
Join Date: Jul 2007
Posts: 15
ktcm is on a distinguished road

Re: Vector of user defined type


Thanks so much for your help. I didn't realise I was tripping myself up with the overloaded assignment operator, which I was declaring as part of a question requirement and did not intend to use. But I guess I've learnt the importance of using the correct function signatures when over-riding functions.
  #7  
Old 09-Sep-2007, 11:02
davis
 
Posts: n/a

Re: Vector of user defined type


Quote:
Originally Posted by ktcm
Thanks so much for your help. I didn't realise I was tripping myself up with the overloaded assignment operator, which I was declaring as part of a question requirement and did not intend to use. But I guess I've learnt the importance of using the correct function signatures when over-riding functions.

Something to remember when defining and implementing your own classes is that if you do not explicitly define and therefore implement ctor/dtor/cctor and assignment operator, the default actions of compiling will do it for you. You will not see these in your code, but you will see them in your object file(s). The following code will compile and execute:

CPP / C++ / C Code:
class Foo
{
};

int main()
{
    Foo f;
    Foo f2 = f;

    return 0;
}


This will compile and run, even though we have nothing in Foo.


:davis:
  #8  
Old 13-Sep-2007, 10:28
ktcm ktcm is offline
New Member
 
Join Date: Jul 2007
Posts: 15
ktcm is on a distinguished road

Re: Vector of user defined type


Ok, I'll take note of that. Thanks for your help =)
 

Recent GIDBlogFirst week of IA training by crystalattice

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Global Variables Kalvorod CPP / C++ Forum 11 21-Feb-2007 12:07
Hard drive/CPU Diagnoses Issues binarybug Computer Hardware Forum 1 22-Jan-2007 19:23
[Include] Doubly-linked List dsmith C Programming Language 6 14-Apr-2006 13:12
User defined headers davis Miscellaneous Programming Forum 6 16-Feb-2006 18:40
C++ PhoneBook marita CPP / C++ Forum 46 12-Jun-2005 12:10

Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 05:06.


vBulletin, Copyright © 2000 - 2008, Jelsoft Enterprises Ltd.