在C++工作了15年后,我发现我完全不理解参考文献......
class TestClass
{
public:
TestClass() : m_nData(0)
{
}
TestClass(int n) : m_nData(n)
{
}
~TestClass()
{
cout << "destructor" << endl;
}
void Dump()
{
cout << "data = " << m_nData << " ptr = 0x" << hex << this << dec << endl;
}
private:
int m_nData;
};
int main()
{
cout << "main started" << endl;
TestClass& c = TestClass();
c.Dump();
c = TestClass(10);
c.Dump();
cout << "main ended" << endl;
return 0;
}
// prints:
// main started
// data = 0 ptr = 0x0012FF54
// destructor
// data = 10 ptr = 0x0012FF54
// main ended
// destructor
我从这个测试中了解到,TestClass实例是在堆栈上创建的(这是正确的吗?)并由第一个TestClass构造函数初始化.分配此实例时:加载主函数或执行引用赋值时?当它被摧毁?
第二个引用后,分配对象地址不会更改.这是否意味着析构函数和构造函数应用于同一个内存区域?或者内存被释放(在堆栈上动态?)并再次分配?
我知道堆栈和堆分配对象的生命周期,它们的构造函数和析构函数.但是我无法理解这个程序到底发生了什么.
编辑: 谢谢大家.我试图在这个测试中重现一些其他(更复杂的)程序行为.你的评论帮助我理解了我的错误以及我正在与之抗争的其他计划......
固定代码是:
int main()
{
cout << "main started" << endl;
TestClass t;
TestClass& c(t);
c.Dump();
c = TestClass(10);
c.Dump();
cout << "main ended" << endl;
return 0;
}
您的代码遇到了多个问题,最终没有意义.但是,让我们破解它.
1)您只能将临时绑定到const引用,从而延长其生命周期:
const TestClass & c = TestClass();
Run Code Online (Sandbox Code Playgroud)
2)现在我们不能使用dump,因为你没有声明它const:
void Dump() const
Run Code Online (Sandbox Code Playgroud)
3)说c = TestClass()是一项任务.但是,c现在是一个无法分配给const的引用,因为赋值是非常量的(出于显而易见的原因).让我们解决这个问题:
const_cast<TestClass&>(c) = TestClass(10);
Run Code Online (Sandbox Code Playgroud)
现在我们已经为临时但扩展的对象分配了一个新值c,并且它们应该是:
main started
data = 0 ptr = 0x0xbfa8219c
destructor
data = 10 ptr = 0x0xbfa8219c
main ended
destructor
Run Code Online (Sandbox Code Playgroud)
指针是相同的,因为只有一个对象,即引用的(临时)对象c.分配给它的是一般的未定义行为的黑客攻击,但为了本演示的目的,我们侥幸逃脱它.
中间析构函数是第二个临时析构函数TestClass(10).
| 归档时间: |
|
| 查看次数: |
1823 次 |
| 最近记录: |