为什么在函数内部初始化时 C++ 对象会被销毁?我能做些什么来防止它?
Why are C++ objects destroyed when initialized inside function? What can I do to prevent it?
这里,我压栈的时候,为什么对象被销毁了?
#include <iostream>
#include <stack>
class One
{
private:
int i;
public:
One(int i) {this->i = i;}
~One() {std::cout << "value " << this->i << " is destroyed\n";}
};
int main()
{
std::stack<One> stack;
stack.push(One(1));
stack.push(One(2));
std::cout << "Now I'll stop\n";
}
我预计在 Now I'll stop
之前看不到任何输出。但是我明白了
value 1 is destroyed
value 2 is destroyed
Now I'll stop
value 1 is destroyed
value 2 is destroyed
想要不让他们破坏怎么办?
One(1)
和One(2)
构造两个临时对象,传递给push
,然后复制(移动)到stack
。完整表达式后立即销毁临时变量。
如果您想避免构建临时对象,您可以使用 emplace
。
Pushes a new element on top of the stack. The element is constructed in-place, i.e. no copy or move operations are performed.
例如
stack.emplace(1);
stack.emplace(2);
执行此操作时 stack.push(One(1));
它会创建一个临时对象,称为 One(1)
的右值,然后将其复制到 Stack。所以复制后,临时对象被销毁。
让我在 中添加一个说明细节,它解决了实际问题。
如果你在 class One
中添加一个 copy constructor,你会更容易理解发生了什么,以及 如何 之间的平衡创造和破坏得以维持。 (对你来说,两次造物获得 4 次破坏不是很神奇吗?)
只要你不定义(或提及)copy constructor,编译器就会为你创建一个具有简单实现的按位复制所有成员。因此,就您而言,您观察到的行为可能令人困惑,但并没有做任何特别糟糕的事情。一旦您添加涉及不仅仅是复制的成员,这当然会改变,例如指向必须在某处销毁的成员的指针...
在下面的示例中,我将输出添加到两个构造函数,并将在构造函数主体中分配成员切换为 initialiser list:
class One
{
public:
One(int rhs): i(rhs) {
std::cout<< "value " << i << " was created from int\n";
}
One(const One& rhs): i(rhs.i) {
std::cout<< "value " << i << " was created by copy\n";
}
~One() {
std::cout << "value " << i << " is destroyed\n";
}
private:
int i;
};
这里,我压栈的时候,为什么对象被销毁了?
#include <iostream>
#include <stack>
class One
{
private:
int i;
public:
One(int i) {this->i = i;}
~One() {std::cout << "value " << this->i << " is destroyed\n";}
};
int main()
{
std::stack<One> stack;
stack.push(One(1));
stack.push(One(2));
std::cout << "Now I'll stop\n";
}
我预计在 Now I'll stop
之前看不到任何输出。但是我明白了
value 1 is destroyed
value 2 is destroyed
Now I'll stop
value 1 is destroyed
value 2 is destroyed
想要不让他们破坏怎么办?
One(1)
和One(2)
构造两个临时对象,传递给push
,然后复制(移动)到stack
。完整表达式后立即销毁临时变量。
如果您想避免构建临时对象,您可以使用 emplace
。
Pushes a new element on top of the stack. The element is constructed in-place, i.e. no copy or move operations are performed.
例如
stack.emplace(1);
stack.emplace(2);
执行此操作时 stack.push(One(1));
它会创建一个临时对象,称为 One(1)
的右值,然后将其复制到 Stack。所以复制后,临时对象被销毁。
让我在
如果你在 class One
中添加一个 copy constructor,你会更容易理解发生了什么,以及 如何 之间的平衡创造和破坏得以维持。 (对你来说,两次造物获得 4 次破坏不是很神奇吗?)
只要你不定义(或提及)copy constructor,编译器就会为你创建一个具有简单实现的按位复制所有成员。因此,就您而言,您观察到的行为可能令人困惑,但并没有做任何特别糟糕的事情。一旦您添加涉及不仅仅是复制的成员,这当然会改变,例如指向必须在某处销毁的成员的指针...
在下面的示例中,我将输出添加到两个构造函数,并将在构造函数主体中分配成员切换为 initialiser list:
class One
{
public:
One(int rhs): i(rhs) {
std::cout<< "value " << i << " was created from int\n";
}
One(const One& rhs): i(rhs.i) {
std::cout<< "value " << i << " was created by copy\n";
}
~One() {
std::cout << "value " << i << " is destroyed\n";
}
private:
int i;
};