题
最近我发现,当我有一个类中三分球,我需要指定一个拷贝构造函数。
要了解到,我已经提出了以下简单的代码。它编译,但给了我运行时错误进行拷贝构造函数时。
我试图只将值从所复制的对象的指针复制,但是避免分配相同的地址。
那么,什么是错在这里?
class TRY{
public:
TRY();
~TRY();
TRY(TRY const &);
int *pointer;
void setPointer(int);
};
void TRY::setPointer(int a){
*pointer = a;
return;
}
TRY::TRY(){}
TRY::~TRY(){}
TRY::TRY(TRY const & copyTRY){
int a = *copyTRY.pointer;
*pointer = a;
}
int main(){
TRY a;
a.setPointer(5);
TRY b = a;
b.setPointer(8);
cout << "Address of object a = " << &a << endl;
cout << "Address of object b = " << &b << endl;
cout << "Address of a.pointer = " << a.pointer << endl;
cout << "Address of b.pointer = " << b.pointer << endl;
cout << "Value in a.pointer = " << *a.pointer << endl;
cout << "Value in b.pointer = " << *b.pointer << endl;
return 0;
}
我将使用这个概念的其他类,有很多在它的指针,在这里我需要的所有值从对象复制到其他的。复制是此代码最初必要,所以我想保持复制可能性(I将不被隐藏拷贝构造为私有的)。
此外,真正的I类需要实现具有像10个球,并可能随时间发生变化。是不是有在C深拷贝构造函数有点更聪明的方式++?......
解决方案
使用int* pointer
刚才定义一个指针,但还没有分配的任何内存的声明。首先,你应该使它指向正确的内存位置分配一些这样的记忆:int* pointer = new int
。然后在拷贝构造函数再次,你必须分配的内存复制的对象。另外,不要忘记使用删除在析构函数,以释放存储器。
希望这个例子有助于:
class B
{
public:
B();
B(const B& b);
~B();
void setVal(int val);
private:
int* m_p;
};
B::B()
{
//Allocate the memory to hold an int
m_p = new int;
*m_p = 0;
}
B::B(const B& b)
{
//Allocate the memory first
m_p = new int;
//Then copy the value from the passed object
*m_p = *b.m_p;
}
B::~B()
{
//Release the memory allocated
delete m_p;
m_p = NULL;
}
void B::setVal(int val)
{
*m_p = val;
}
其他提示
最近我发现,当我 一个类中有一个指针,我需要 指定一个复制构造。
这是不完全真实的。当你在你的类指针,并使用new
分配内存,那么你不必担心拷贝构造函数。另外,不要忘了赋值运算符和析构函数。
你必须删除使用delete
分配的内存。
这就是所谓的法的三巨头。
示例:
~Matrix(); //Destructor
Matrix(const Matrix& m); //Copy constructor
Matrix& operator= (const Matrix& m); //Assignment operator
如果你想要做一个深拷贝,你当然也必须分配新的内存来保存值。如果原来有一个指针指向一个int,你不希望复制使用相同的指针值,你必须分配新的内存来容纳一个int,然后复制的价值在那里。
您的例子是不是很清楚,它不会显示你的拷贝构造函数的实现,或pointer
成员如何被初始化。
最近我发现,当我 一个类中有一个指针,我需要 指定一个复制构造
往往不是它是一个好主意,简单地通过声明它(以及分配新建分配FY操作者)的私人和不执行它禁用它。
如果它有一个指针指向一个普通类型,然后
A::A(const A& a):
pointer_( new int( *a.pointer_ ) )
{
}
,如果它有一个指针指向一些基类然后
A::A(const &a ):
pointer_( a.pointer_->clone() )
{
}
克隆是原型模式
不要忘记删除指针在析构
A::~A()
{
delete pointer_;
}
要修复您示例
TRY::TRY(TRY const & copyTRY){
int a = *copyTRY.pointer;
pointer = new int(a);
}
您的问题是在这条线就在这里:
*pointer = a;
所有,通常发生在你的默认构造函数的东西,还没有发生,包括内存*pointer
分配。
解决方法是为一个整数分配内存。您可以使用malloc
和朋友或new
这一点,但要确保它是你在你的默认构造函数使用同样的方法,因为你只有一次析构函数,并调用必须匹配。
如果一个成员明智的(浅)的副本是好的,那么你就没有做任何事情。如果你想有一个深拷贝,你必须为所有成员的副本分配新的存储空间。
在写一个拷贝构造函数,你应该为所有成员分配内存。 在你的情况:
TRY::TRY(TRY const & copyTRY){
pointer = new int(*(copyTry.pointer));
}
算=在某种程度上类似,但没有内存分配。
TRY& operator=(TRY const& otherTRY){
this->a = *(otherTry.pointer)
return *this
}
通常情况下,如果你需要写你所做的是错的拷贝构造函数或赋值操作符。离开拷贝构造函数和赋值操作符的标准库的实现者。撰写已可复制和可分配的要素类和你不会写自己的。
例如,也许这INT *构件应该是一个std ::矢量代替。
如果您不能使类的默认可复制/分配,也许你可以把它不可复制/分配通过声明,但不执行,私人拷贝构造函数和赋值操作符。
只有当以上都不是你应该实现自己的拷贝构造函数或赋值操作符是可行的。