template <class T>
class ListNode {
public:
T* data;
ListNode<T>* next;
}
让我们说我有一个列表节点模板,代码中的某个地方我想获得数据的副本 - 这意味着不是数据指针(T *)的副本,而是新指针(T *)指向记忆中另一个具有相同信息的地方。
使用C ++模板时该怎么办?如果我不知道T的类型,我该如何复制(*数据)。
答案 0 :(得分:1)
编译器知道 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 :(得分:0)
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有一个复制构造函数,这将有效。如果没有,编译器会给你一个错误(可能是一个非常神秘的错误)
答案 2 :(得分:0)
使用operator =或复制构造函数。标准做法是,这两者都会产生对象的副本。
所以,例如:
T *p = other_pointer;
*p = *data;
或者
T* copy = new T(*data);
答案 3 :(得分:0)
创建模板化类型的副本时,实际上您不必担心类型,并在该类型的复制构造函数或赋值运算符上执行该任务:
template <class T>
class ListNode {
public:
T* data;
ListNode<T>* next;
T* getCopy() { new T(*data); } // get copy of "data"
};
假设您将ListNode<T>
用于class A
,那么您可以为A(和赋值运算符)定义一个复制构造函数:
class A {
public:
A(const A& copy);
};
现在调用ListNode<T>::getCopy()
时,它将在内部调用A的复制构造函数。