template <class T>
class ListNode {
public:
T* data;
ListNode<T>* next;
}
可以說我有一個列表節點模板,並在代碼中的某處我想獲取數據的副本 - 意味着不是指向數據(T *)的指針的副本,而是一個新的指針(T *),它將指向存儲器中具有相同信息的另一個地方。C++模板問題
如何在使用C++模板時執行此操作?我怎樣才能複製(*數據),如果我不知道什麼是
template <class T>
class ListNode {
public:
T* data;
ListNode<T>* next;
}
可以說我有一個列表節點模板,並在代碼中的某處我想獲取數據的副本 - 意味着不是指向數據(T *)的指針的副本,而是一個新的指針(T *),它將指向存儲器中具有相同信息的另一個地方。C++模板問題
如何在使用C++模板時執行此操作?我怎樣才能複製(*數據),如果我不知道什麼是
T有要被複制施工的,這樣就可以做
template <class T>
ListNode<T>::ListNode(const ListNode<T>& src)
{
...
// given a preexisting copy, src, create a new T to
// perform a copy
T* destT = new T(*srcT);
}
T的類型。如果T有一個拷貝構造函數,這將起作用。如果沒有,編譯器會給你一個錯誤(可能是一個非常神祕的錯誤)
NM ...它涉及咖啡,它不是你的最終目的。 – 2011-04-22 14:21:27
爲什麼編譯器應該給出錯誤; 編譯器不會生成默認的拷貝構造函數嗎? – iammilind 2011-04-22 14:29:11
使用運算符=或複製構造函數。這是標準做法,它們都會生成對象的副本。
因此,舉例來說:
T *p = other_pointer;
*p = *data;
或者
T* copy = new T(*data);
適用於允許切片的「生成副本」的值。 – 2011-04-22 14:31:25
@本:沒有標準的虛擬複製功能,所以你拿你可以得到的。 – 2011-04-22 17:24:10
當創建一個模板類型的副本,實際上你不用擔心的類型,例如,住該任務上的副本構造函數或該類型的賦值運算符:
template <class T>
class ListNode {
public:
T* data;
ListNode<T>* next;
T* getCopy() { new T(*data); } // get copy of "data"
};
假設您使用此ListNode<T>
class A
,那麼你可以有在定義(和賦值運算符以及)拷貝構造函數:
class A {
public:
A(const A& copy);
};
現在,當ListNode<T>::getCopy()
被調用時,它會調用的內部拷貝構造函數。
-1:每次有人要求複製時,潛在的內存泄漏可能不是一個好設計......將其包裝在智能指針中,或者最好提供顯式拷貝構造函數和/或賦值運算符。 – AJG85 2011-04-22 15:02:42
@ AJG85,我不這麼認爲是內存泄漏。提問者詢問'T *'的副本,它可以存儲在其他對象的'data'成員中,並且可以在析構函數中被刪除。 – iammilind 2011-04-23 04:40:33
您返回一個像這樣的副本:'T getCopy()const {* data; }'你正在做的是在堆上分配內存並在一個** public **方法中返回一個指向它的指針,這很容易導致內存泄漏和孤兒指針......調用你的方法的任何人都必須存儲指針並調用delete '以避免內存泄漏,沒有例外。 – AJG85 2011-04-25 15:47:27
編譯器知道T的類型。不知道的是指向多少個實例T。在獲得實際的實現方面,簡短的答案是不要使用指針類型。改用容器。由於無論如何您都在複製節點數據,所以開銷很小。下面明顯的例子:
template <class T>
class ListNode {
public:
// use a vector as the container
std::vector<T> data;
ListNode<T>* next;
// initializer from pointer primitive
ListNode(const T* ps,size_t elements)
{
data.assign(ps,ps+elements);
}
// copy templated instance
ListNode(const ListNode& arg)
{
data = arg.data;
}
// assignment
ListNode& operator=(const ListNode& arg)
{
if (this != &arg)
{
data = arg.data;
}
return *this;
}
};
實際使用量將與此類似:
{
const char* ps = "Hello World";
ListNode<char> ln1(ps,strlen(ps));
ListNode<char> ln2 = ln1;
}
你可以,當然,變得更加複雜,解決方案,但他們都將涉及保留的實例數的軌道鍵入指針指向的T。
+1:儘管範例的範圍仍然是一個簡單的選擇,簡單是好的。 – AJG85 2011-04-22 15:16:09
當你知道類型時,你如何做到這一點?它適用於模板類型。 – 2011-04-22 14:12:38
您*知道類型...'T' – 2011-04-22 14:13:42
@Konrad:或者,它同樣不適用於非模板。到目前爲止所有的答案都會導致切片。 – 2011-04-22 14:28:32