gpt4 book ai didi

c++ - auto_ptr_ref 实现问题

转载 作者:太空宇宙 更新时间:2023-11-04 11:51:57 26 4
gpt4 key购买 nike

关于 auto_ptr<> 和 auto_ptr_ref<> 的内部实现,我查看了不同的来源。我有这个问题,我不知道为什么。

.... 从函数返回“auto_ptr”时,编译器发现没有合适的构造函数来复制构造返回的对象。但是有转换为'auto_ptr_ref'和ctor采用'auto_ptr_ref'构造'auto_ptr'。因此,编译器创建一个“auto_ptr_ref”,它基本上只包含对原始“auto_ptr”的引用,然后从该对象构造一个“auto_ptr”。就是这样(好吧,当返回一个对象时,编译器通常会经历两次这个过程,因为返回的值被复制到某处,但这不会改变过程)......(引用 http://www.josuttis.com/libbook/auto_ptr.html)

在这个例子中,我模拟了 auto_ptr<> 和 auto_ptr_ref<> 的实现,并且能够生成显示编译器确实经历了两次过程

的结果

该示例具有以下基本特征:

1) A 的复制构造函数不采用 const 引用。2) A有转换运算符B3) A有构造函数A(B);

class B {
};

class A {
public:

A () {
printf("A default constructor() @ %p\r\n", this);
}

A(B) {
printf("constructor(B) @ %p\r\n", this);
}
A (A &a) {
printf("copy constructor(non-const) @ %p\r\n", this);
}

operator B() {
printf("A convertion constructor(B) @ %p\r\n", this);
return B();
}
};


A foo()
{
return A();
}

int main()
{
A a(foo());
}

所以当A a(foo()))被执行

1) foo() 生成临时对象 X2)X转换为B型3)构造函数A(B)用于构造对象a

这是输出:

A default constructor() @ 0xbfea340f
A convertion constructor(B) @ 0xbfea340f
constructor(B) @ 0xbfea344f
A convertion constructor(B) @ 0xbfea344f
constructor(B) @ 0xbfea344e

我们可以看到编译器两次完成转换构造步骤 2 和 3。

这是为什么?

最佳答案

如果您正在调用一个返回类类型的函数,基本上会发生以下情况:

  • 在调用时,调用函数在堆栈上为临时返回值保留一些空间(它必须由调用函数完成,因为被调用函数在堆栈上分配的任何内容函数返回后立即释放)。它将那个空间的地址传递给被调用的函数。

  • 在执行 return 语句时,被调用函数根据提供给 return 语句的参数将返回值构造到调用函数提供的空间中。在您的情况下,该参数是临时 A 值。

  • 函数返回后,调用者使用被调用函数构造的临时值来执行代码要求的任何操作。在您的例子中,您使用它从中构造一个局部变量。

因此,您从现有对象两次构造一个 A 类型的新对象:首先,构造临时返回值(其生命周期在函数foo 返回,直到声明结束)从 return 语句中显式生成的临时变量(整个生命周期结束于完整表达式的末尾,在这种情况下等同于从 foo 返回)。其次,从 foo 返回的临时变量初始化局部变量 a

当然,由于没有合适的复制构造函数可用,在两种 情况下,您都会经历B 转换。这是可行的,因为 return 进行了直接初始化,而对于 a,您明确编码了这种直接初始化。

关于c++ - auto_ptr_ref 实现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17820364/

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