簡體   English   中英

C ++中的構造函數副本,列表,指針和模板

[英]Constructor copy, list, pointers and template in 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>          ]

這是我的PElement類:

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

我不知道如何解決我的復制構造函數PElement,這-> v =新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;
}
*/

表達式graphe.lSommets是一個指針,並且您沒有PElement構造函數使用指針。

這可以通過以下方法解決:要么創建一個采用指針的新構造函數,要么(我建議的方式)取消對指針的引用:

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

如果列表不為空,則需要為PElement類提供一個復制初始值設定項,該初始值設定項將復制下一個元素。

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。

以下用於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(*ov) ),否則可能會考慮按值存儲在列表元素中。

然后可以在圖形副本構造函數中使用它:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM