Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error C2558 - copy constructor

Tags:

c++

When I compile my class, I get a serious error:

C2558 no copy constructor available or copy constructor is declared 'explicit'

But my copy constructor is neither private nor explicit!

Header:

#include "Csequence.h"

using namespace std;

class Cnoeud
{
private:
    Cnoeud *oNOEpere;
    vector<Cnoeud> oNOEfils;
    Csequence oNOEsequence;
    bool oNOEStatut;

public:
    // Liste des constructeurs
    Cnoeud();
    Cnoeud(Cnoeud &);
    ~Cnoeud(){}

    // Liste des accesseurs et des modificateurs
    Cnoeud * NOEAfficherpere (){ return oNOEpere;}
    vector<Cnoeud> NOEAfficherfils() {return oNOEfils;}
    Csequence NOEAffichersequence() {return oNOEsequence;}
    bool NOEAfficherstatut() { return oNOEStatut;}
    void NOEModifierpere(Cnoeud oNOEp){ *oNOEpere=oNOEp;}
    void NOEModifierfils(vector<Cnoeud>);
    void NOEModifiersequence(Csequence oNOEs){oNOEsequence = oNOEs;}
    void NOEModifierstatut(bool {oNOEStatut = b;}

    // Liste des fonctions membres
    void NOEViderfils(){ oNOEfils.clear();}

    // Surcharge de l'opérateur d'affectation
    Cnoeud & operator=(Cnoeud &) ;
};

Source:

Cnoeud.cpp

#include <iostream>
#include <vector>
#include "Cnoeud.h"

using namespace std;

Cnoeud::Cnoeud()
{
    oNOEStatut= 0;
    oNOEsequence.SEQInitialiserdatesfin(); 
    oNOEsequence.SEQInitialisersequence();
    oNOEpere = NULL;
}

Cnoeud::Cnoeud(Cnoeud & oNOE)
{
    oNOEStatut= oNOE.oNOEStatut;
    oNOEsequence = oNOE.NOEAffichersequence(); 
    oNOEpere = oNOE.NOEAfficherpere();
    oNOEfils.clear();
    vector<Cnoeud>::iterator it;
    for(it=oNOE.NOEAfficherfils().begin();it!=oNOE.NOEAfficherfils().end();it++)
    {
        oNOEfils.push_back(*it);
    }
}
like image 336
undertaker705 Avatar asked Jan 13 '11 10:01

undertaker705


3 Answers

That Cnoeud(Cnoeud &) isn't a copy constructor as it is expected by most code using this class. A copy constructor should be

Cnoeud(const Cnoeud &); 

And why wouldn't you make that argument const? A copy constructor certainly shouldn't alter the object it copies from. Note that the same applies to your assignment operator. Also, those accessors should be const member functions:

Cnoeud * NOEAfficherpere () const { return oNOEpere;}
//                          ^^^^^

See this answer about not using const.

like image 118
sbi Avatar answered Nov 04 '22 16:11

sbi


Copy constructor takes a const reference- that is,

Cnoeud::Cnoeud(const Cnoeud& oNOE)

like image 25
Puppy Avatar answered Nov 04 '22 16:11

Puppy


Cnoeud( Cnoeud & ) is not the normal signature for a copy-constructor although it is sometimes used to "transfer ownership" when copying, i.e. it moves something from the origin to the new object. This is commonly used to get around the issues of which object is going to "clean up" after use when you do not desire to use reference-counted pointers.

With C++0x there will be move semantics with r-value references where you can do Cnoeud( Cnoeud && ) to "move" an object that is not-copyable but can be returned from a function.

It is not safe to use objects with transfer-ownership semantics (like auto_ptr) in collections like vector. You are lucky in a sense that you hit a compiler error because it saved you the pain of a runtime error later - much harder to find the problem.

If you want a proper copy-constructor then pass the parameter as const reference (as other have suggested).

By the way, in your "copy constructor" it appears that

oNOEfils.clear();
vector<Cnoeud>::iterator it;
for(it=oNOE.NOEAfficherfils().begin();it!=oNOE.NOEAfficherfils().end();it++)
{
oNOEfils.push_back(*it);
}

could easily be replaced by

oNOEfils = oNOE.NOEAfficherfils();

More efficient to write (one-liner) and almost certainly more efficient to run too.

like image 2
CashCow Avatar answered Nov 04 '22 17:11

CashCow