Luk*_*cky 20 c++ pointers memory-management copy-constructor
我有以下代码来测试我对C++中基本指针的理解:
// Integer.cpp
#include "Integer.h"
Integer::Integer()
{
value = new int;
*value = 0;
}
Integer::Integer( int intVal )
{
value = new int;
*value = intVal;
}
Integer::~Integer()
{
delete value;
}
Integer::Integer(const Integer &rhInt)
{
value = new int;
*value = *rhInt.value;
}
int Integer::getInteger() const
{
return *value;
}
void Integer::setInteger( int newInteger )
{
*value = newInteger;
}
Integer& Integer::operator=( const Integer& rhInt )
{
*value = *rhInt.value;
return *this;
}
// IntegerTest.cpp
#include <iostream>
#include <cstdlib>
#include "Integer.h"
using namespace std;
void displayInteger( char* str, Integer intObj )
{
cout << str << " is " << intObj.getInteger() << endl;
}
int main( int argc, char* argv[] )
{
Integer intVal1;
Integer intVal2(10);
displayInteger( "intVal1", intVal1 );
displayInteger( "intVal2", intVal2 );
intVal1 = intVal2;
displayInteger( "intVal1", intVal1 );
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
此代码完全按预期工作,它打印出来:
intVal1 is 0
intVal2 is 10
intVal1 is 10
Run Code Online (Sandbox Code Playgroud)
但是,如果我删除了复制构造函数,它会输出如下内容:
intVal1 is 0
intVal2 is 10
intVal1 is 6705152
Run Code Online (Sandbox Code Playgroud)
我不明白为什么会这样.我的理解是,当赋值给不存在的对象时,使用复制构造函数.这里intVal1确实存在,为什么不调用赋值运算符?
AnT*_*AnT 20
在分配期间不使用复制构造函数.在将参数传递给displayInteger函数时,将使用您的案例中的复制构造函数.第二个参数按值传递,这意味着它由复制构造函数初始化.
您的版本的复制构造函数会对类拥有的数据执行深度复制(就像您的赋值运算符一样).因此,一切都适用于您的版本的复制构造函数.
如果删除自己的复制构造函数,编译器将隐式生成一个.编译器生成的复制构造函数将执行对象的浅复制.这将违反"三法则"并破坏您班级的功能,这正是您在实验中观察到的.基本上,第一次要求displayInteger损坏您的intVal1物体,第二次要求displayInteger损害您的intVal2物体.之后,两个对象都被破坏,这就是第三个displayInteger调用显示垃圾的原因.
如果您将声明更改displayInteger为
void displayInteger( char* str, const Integer &intObj )
Run Code Online (Sandbox Code Playgroud)
即使没有显式的复制构造函数,你的代码也会"工作".但在任何情况下忽视"三个规则"都不是一个好主意.以这种方式实施的类要么必须服从"三规则",要么必须是不可复制的.
| 归档时间: |
|
| 查看次数: |
20588 次 |
| 最近记录: |