错误C2558 - 复制构造函数

时间:2011-01-13 10:12:28

标签: c++

当我编写课程时,我收到了一个严重的错误:

  

C2558没有可用的复制构造函数或复制构造函数被声明为'explicit'

但是我的拷贝构造函数既不是私有的也不是显式的!

部首:

#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 &) ;
};

来源:

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);
    }
}

3 个答案:

答案 0 :(得分:18)

Cnoeud(Cnoeud &)不是复制构造函数,因为大多数代码都使用此类。复制构造函数应该是

Cnoeud(const Cnoeud &); 

你为什么不提出这个论点const?复制构造函数当然不应该改变它复制的对象。请注意,这同样适用于您的赋值运算符。此外,这些访问者应该是const成员函数:

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

请参阅this answer有关未使用const的信息。

答案 1 :(得分:3)

复制构造函数采用const引用 - 即

Cnoeud::Cnoeud(const Cnoeud& oNOE)

答案 2 :(得分:2)

Cnoeud( Cnoeud & )不是复制构造函数的正常签名,尽管它有时用于在复制时“转移所有权”,即它将某些东西从原点移动到新对象。这通常用于解决在您不希望使用引用计数指针时,在使用后哪个对象将“清理”的问题。

使用C ++ 0x,将会移动带有r值引用的语义,您可以Cnoeud( Cnoeud && )“移动”一个不可复制但可以从函数返回的对象。

在像vector这样的集合中使用具有转移所有权语义的对象(如auto_ptr)是不安全的。从某种意义上说,你遇到编译器错误是幸运的,因为它为你节省了运行时错误的痛苦 - 更难找到问题。

如果你想要一个合适的拷贝构造函数,那么将参数作为const引用传递(正如其他人所建议的那样)。

顺便说一句,在你的“复制构造函数”中,它似乎是

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

很容易被

取代

oNOEfils = oNOE.NOEAfficherfils();

写作效率更高(单线程),运行效率几乎肯定更高。