2015-02-23 16 views
1

我愿做一个拷贝构造函数和定义=运营商为这个下面的类构造副本,列表指针和模板在C++

template <class S, class T> 
class Graphe 
{ 
protected: 
int prochaineClef; 
public: 

PElement< Sommet<T> > * lSommets; // liste de sommets 
PElement< Arete<S,T> > * lAretes; // liste d'arêtes 

Graphe(const Graphe<S,T> & graphe); 
const Graphe<S,T> & operator = (const Graphe<S,T> & graphe); 
} 

到目前为止,我已经试过这大概构造:

template <class S, class T> 
Graphe<S,T>::Graphe(const Graphe<S,T> & graphe) 
{ 
PElement< Sommet<T> > * nouvelListeSommet = new PElement<Sommet<T>>(*graphe.lSommets); 
PElement< Arete<S,T> > * nouvelListeAretes = new PElement<Arete<S,T>>(*graphe.lAretes); 
this->prochaineClef = graphe.prochaineClef; 
this->lAretes = nouvelListelAretes; 
this->lSommets = nouvelListeSommet; 

//nouvelListeSommet = graphe.lSommets->copieListe(graphe.lSommets); 
//nouvelListelAretes = graphe.lAretes->copieListe(graphe.lAretes); 

} 

So i got this error saying 
\visual studio 2012\projects\ihm\tp2graphe\tp2graphe\pelement.h(123): error C2664: 'PElement<T>::PElement(T *,PElement<T> *)' : can't convert param1 from 'PElement<T> *const ' to 'Sommet<T> *' 
1>   with 
1>   [ 
1>    T=Sommet<InfoSommetCarte> 
1>   ] 
1>   and 
1>   [ 
1>    T=Sommet<InfoSommetCarte> 
1>   ] 
1>   and 
1>   [ 
1>    T=InfoSommetCarte 
1>   ] 

这里是我的P成分类:

class PElement 
{ 
public : 
T * v; 
PElement<T> * s; 


PElement(T * v, PElement<T> * s); 
PElement(PElement<T> & l); 
} 

template<class T> 
PElement<T>::PElement(PElement<T> & l) 
{ 
    //this->v = new T(l->v); 
    this = new PElement<T>(l,this); 
} 

我不知道如何解决我的拷贝构造函数P成分 is this-> v = new T(l-> v)是否正确?

这里是我的错copieListe方法:

/* 
template<class T> 
PElement<T> * PElement<T>::copieListe(PElement<T> * original) 
{ 
    for(int i = 0; i < PElement<T>::taille(original);i++) 
    { 
     this->insertionTete(original->v,this); 
     original = original->s; 
    } 
    return this; 
} 
*/ 
+0

在你要复制的P成分列表中的拷贝构造函数初始化图形。 – chmike 2015-02-23 14:21:00

+0

准确完整地再现编译器消息。标记与编译器报告的行号对应的源代码行。 – 2015-02-23 14:21:50

+0

你需要下面的代码:lSommets = copieListe(graphe.lSommets);.然后您需要提供copieListe方法/函数。它返回一个PElement < Sommet> *,它是链接列表的副本。 – chmike 2015-02-23 14:29:10

回答

0

您需要为P成分级副本初始化,下副本元素如果列表不是空的。

template <class T> 
class PElement 
{ 
public : 
    T * v; 
    PElement<T> * s; 

    PElement(T * v, PElement<T> * s = nullptr); 
    PElement(const PElement<T> & l); 
}; 

template<class T> 
PElement<T>::PElement(T * v, PElement<T> * s) : v(v), s(s) {} 

template<class T> 
PElement<T>::PElement(const PElement<T> & l) 
{ 
    v = new T(*l.v); 
    s = l.s ? new PElement<T>(*l.s) : nullptr; 
} 

然后,这是该图类的副本初始化

template <class S, class T> 
Graphe<S,T>::Graphe(const Graphe<S,T> & graphe) 
{ 
    lSommets = graphe.lSommets ? new PElement<Sommet<T>>(*graphe.lSommets) : nullptr; 
    lAretes = graphe.lAretes ? new PElement<Arete<S,T>>(*graphe.lAretes) : nullptr; 
    prochaineClef = graphe.prochaineClef; 
} 

我不会实现它以这种方式,因为名单是递归复制,你可能会得到一个堆栈溢出如果列表很长。正如@Rerito建议的,你应该使用std :: list来代替。这段代码示例显示了你应该怎么做才能避免你得到的错误。

PElement的复制构造函数需要PElement上的引用。这就是为什么我们通过* graphe.lSommets和* graphe.lAretes。

+0

谢谢,它帮助了很多,但我仍然在“v = new T(l.v);” - > C2664:无法将'Sommet * const'转换为'const Sommet &'。任何想法?是的@Rerito关于那个设计,我没有做,我被迫与这些类工作,我希望我可以重做整个东西使用2 STL载体.. – rilent 2015-02-23 17:06:51

+0

我已经改变它与“v = new T(* lv );”我现在没有得到任何错误,但它既没有复制也没有复制 – rilent 2015-02-23 17:13:34

+0

错误是“v = new T(l.v);”应该是“v = new T(* l.v);”以便可以使用复制初始值设定项。我会在我的答案的代码中解决这个问题。 – chmike 2015-02-24 09:19:48

0

表达graphe.lSommets指针和你没有PElement构造采用指针。

这可以通过解决要么使一个新的构造函数指针或间接引用指针(我推荐的方式):

new PElement<Sommet<T>>(*graphe.lSommets); 
//     ^
//      | 
// Note the dereference operator 
+0

重做整个东西这不正确,因为PElement是链表的一个元素。这会破坏链表。 – chmike 2015-02-23 14:23:48

0

以下PElement<T>的复制构造函数应该可以工作。

template <typename T> 
PElement<T>::PElement(const PElement<T> &o) : v(nullptr), s(nullptr) { 
    // I assume you are marking the end of the list by a nullptr sentinel 
    if (nullptr != o.s) { 
     s = new PElement<T>(*o.s); 
    } 
    // Two options for `v`, pick one... 
    v = o.v; // Shallow copy of the T pointers 
    v = new T(*o.v) // Deep copy of the T pointers... Assume T is copyable 
} 

它将递归的每个元素在列表中击中nullptr定点复制时停止。

如果你想保持PElement它(使用T*用来存放模板类型的东西)的方式,你可能要执行深拷贝(因此你挑this->v = new T(*o.v)),否则你可能会值列表考虑将元素。

然后,您可以在您的图形拷贝构造函数使用它:

template <typename S, typename T> 
Graphe<S,T>::Graphe(const Graphe<S,T> &g) { 
    lSommets = new PElement<Sommet<T>>(*g.lSommets); 
    lAretes = new PElements<Arete<S,T>>(*g.lAretes); 
    // ... Whatever work you need ... 
    prochaineClef = g.prochaineClef; 
}