1

我做了所謂的隊列類模板,但我在試圖用一個指針叫工人作爲類型另一個類實例化它的問題。 Queue<Worker*>如何定義指針和動態內存分配的模板?

我認爲這個問題是這種具體的隊列方法:

// Add item to queue 
template <typename Type> 
bool Queue<Type>::enqueue(const Type& item) 
{ 
    if (isfull()) 
     return false; 
    Node* add = new Node; // create node 
    // on failure, new throws std::bad_alloc exception 
    add->item = item; // set node pointers (shallow copying!!!!!) 
    add->next = nullptr; 
    items++; 
    if (front == nullptr) // if queue is empty, 
     front = add; // place item at front 
    else 
     rear->next = add; // else place at rear 
    rear = add; // have rear point to new node 
    return true; 
} 

在類型參數的情況下,是一個指向我需要複製指向的值,而不是地址(我使用動態內存管理)來避免程序崩潰。

我不知道如何與一個模板解決這個問題。

任何幫助?

+0

以及最通用的容器不知道他們持有的指針,因此他們會做淺複製 –

+0

如果您覺得喜歡冒險,可以深入研究[Boost Pointer Containers]的源代碼(http://www.boost.org/doc/libs/1_51_0/libs/ptr_container/doc/ptr_container.html)並查看他們這樣做。 – jrok

回答

1

雖然它會導致一些代碼重複,但您可以創建一個Queue類的專用實例化指針類型。我爲了減少代碼的重複量的建議是建立一個基類各專業類將來自繼承其中基類包含了所有的方法和成員,取決於該類的類型是不會改變用...實例化。

因此,例如:

template<typename T> 
base_queue; //keep everything "common" in this class 

template<typename T> 
queue : public base_queue<T> { ... }; //unspecialized queue class 

template<typename T> 
queue<T*> : public base_queue<T> { ... }; //pointer specialized version 

現在,在您Queue<T*>類的專用版本,您enqueue方法如下所示:

template <typename T> 
bool Queue<T*>::enqueue(const T* item) 
{ 
    //... code 

    add->item = *item; // copy the value being pointed to, not the pointer itself 

    //... more code 

    return true; 
} 
+0

謝謝,我會試試這個。 – Kurospidey

2

使用特性技術。

我的意思是定義簡單的結構,所有的魔法將實施。事情是這樣的DEEP_COPY:

template <typename T> 
    struct deep_copy { 
    void do_copy(T& d, const T& s) 
    { 
     d = s; 
    } 
    }; 

和專業化的指針

template <typename T> 
    struct deep_copy<T*> { 
    void do_copy(T*& d, const T* s) 
    { 
     if(s) d=new(*s); else d=0; }}; 
    } 
    };   

[UPDATE1]更多的細節和更多的例子:

而在你的隊列使用DEEP_COPY:

template <typename T> 
class Queue { 
public: 
    void push_back(const T& elem) 
    { 
     Node* n = new Node(); 
     copyTraits.doCopy(n->elem, elem); 
    } 
private: 
    deep_copy<T> copyTraits; 
}; 

甚至更​​好設置成默認PARAMET呃到你的模板像<>是默認的地圖。

template <typename T, typename CopyTraits = deep_copy<T> > 
class Queue { 
public: 
    void push_back(const T& elem) 
    { 
     Node* n = new Node(); 
     copyTraits.doCopy(n->elem, elem); 
    } 
private: 
    CopyTraits copyTraits; 
}; 

而且不要忘了銷燬方法,如果你希望你的Queue::~Qeueu() d-TOR是安全的:

template <typename T> 
    struct deep_copy { 
    void do_copy(T& d, const T& s) 
    { 
     d = s; 
    } 
    void do_destroy(const T& elem) {} // do nothing 
    }; 


    template <typename T> 
    struct deep_copy<T*> { 
    void do_copy(T*& d, const T* s) 
    { 
     if(s) d=new(*s); else d=0; }}; 
    } 
    void do_destroy(const T& elem) { 
     delete elem; 
    } 
    };   


template <typename T, typename AllocTraits = deep_copy<T> > 
class Queue { 
public: 
    ... 
    ~Queue() { 
     for (n in Nodes) { // pseudo-code 
     allocTraits.doDestroy(n->elem); 
     } 
    } 
private: 
    AllocTraits allocTraits; 
}; 
+0

有趣的...並會節省大量的代碼重複。我必須嘗試一下。謝謝! – Kurospidey

+0

如果你可以編輯/格式化我的文章,請。我從手機輸入......無論如何,這種特質技術在模板世界中非常普遍。值得嘗試和學習 – PiotrNycz

+0

注意我的變化。我不知道你是否使用了這些特性 - 但是doCopy指針的聲明應該引用指向目標(d)的指針:'do_copy(T *&d,const T * s)' – PiotrNycz