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