gpt4 book ai didi

c++ - C++ 引用的工作原理

转载 作者:太空狗 更新时间:2023-10-29 23:33:57 27 4
gpt4 key购买 nike

在 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 构造函数初始化。这个实例是什么时候分配的:是在main函数加载的时候还是在执行引用赋值的时候?什么时候销毁?

第二次引用赋值后,对象地址没有改变。这是否意味着析构函数和构造函数应用于同一内存区域?还是内存被释放(动态?在堆栈上?)并再次分配?

我知道关于堆栈和堆分配对象的生命周期、它们的构造函数和析构函数的一切,但我无法理解这个程序中究竟发生了什么。

编辑:谢谢大家。我试图在这个测试中重现一些其他(更复杂的)程序行为。你的评论帮助我理解了我的错误和我正在与之抗争的另一个程序......

固定代码是:

int main()
{
cout << "main started" << endl;
TestClass t;

TestClass& c(t);
c.Dump();

c = TestClass(10);
c.Dump();

cout << "main ended" << endl;
return 0;
}

2022 年 6 月 29 日的注释:在 Daniel Walker 的最新版本之后,这个问题看起来完全是废话。我对此概不负责。

最佳答案

您的代码存在多个问题,最终将毫无意义。但是,让我们破解它。

1) 您只能将临时对象绑定(bind)到const 引用,从而延长其生命周期:

const TestClass & c = TestClass();

2) 现在我们不能使用dump,因为你没有声明它const:

void Dump() const

3) c = TestClass() 是一个赋值。但是,c 现在是对常量的引用,不能对其赋值,因为赋值是非常量(原因很明显)。让我们解决这个问题:

const_cast<TestClass&>(c) = TestClass(10);

现在我们已经为临时但扩展的对象 c 分配了一个新值,一切都是应该的:

main started
data = 0 ptr = 0x0xbfa8219c
destructor
data = 10 ptr = 0x0xbfa8219c
main ended
destructor

指针是相同的,因为只有一个对象,即 c 引用的(临时)对象。分配给它是一种 hack,通常是未定义的行为,但出于本次演示的目的,我们避开了它。

中间析构函数是第二个临时 TestClass(10) 的析构函数。

关于c++ - C++ 引用的工作原理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7418483/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com