gpt4 book ai didi

C++ vector push_back 方法和临时对象创建

转载 作者:行者123 更新时间:2023-11-28 05:41:07 27 4
gpt4 key购买 nike

下面是 C++ 中 vector 推回方法的签名。

 void push_back (const value_type& val);

下面是代码

class MyInt
{
int *a;
public:
MyInt(int n):a(new int(n)){cout<<"constructor called"<<endl;}
~MyInt(){cout<<"destructor called"<<endl;}
void show(){
cout<<*a<<endl;
}
};


void vector_test(vector<MyInt> &v)
{
MyInt m1(1);
MyInt m2(2);
v.push_back(m1);
v.push_back(m2);
}



Output
-------------
constructor called
constructor called
destructor called
destructor called
destructor called
1
2
destructor called
destructor called

这里我们看到在 vector_test 函数中创建的 2 个对象导致 2 次构造函数调用。但对于析构函数,它被调用了 5 次。

现在我的疑惑和问题是

  1. 为什么构造函数和析构函数的调用次数不匹配?
  2. 我了解到正在创建一些临时对象。但这种机制是如何运作的?
  3. 只是为了测试,我尝试提供一个复制构造函数,但它会导致编译失败。可能是什么原因?
  4. 是否有一些逻辑将 m1 和 m2 的内容复制到新对象中并放入容器中?

如果有人能详细解释一下,我将不胜感激。谢谢..

最佳答案

您还需要为复制构造函数添加日志记录:

MyInt(const MyInt& rhs):a(new int(*rhs.a)){cout<<"copy constructor called"<<endl;}

编译器允许省略某些构造函数调用,即。在以下行中:

MyInt m1 = 1;

您可能希望首先调用复制构造函数来实例化临时 MyInt(1)然后用这个临时调用一个复制构造函数。所以你会看到:

constructor called // for temporary
copy constructor called // for m1
destructor called // for m1
destructor called // for temporary

但由于复制省略编译器将直接实例化您的 m1使用 MyInt(int n) 的实例构造函数,即使您的复制构造函数有副作用(使用 std::cout)。所以没有以上 // for temporary日志将存在。

要使用 gcc 查看此信息,请使用:-fno-elide-constructors禁用复制构造函数省略的选项。

此外,构造函数也是一个好习惯,例如 MyInt(int n)明确的,这是不允许制作MyInt错误的对象实例 - 你必须将其明确化,即 MyInt var; var = static_cast<MyInt>(1); .

关于C++ vector push_back 方法和临时对象创建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37078038/

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