我有以下代码(我将跳过包含和你有什么):
的main.cpp
std::vector <actor> actors;
int main() {
actor (2, 3);
}
actor.h
class actor
{
public:
int x, y;
actor(int, int);
};
actor.cpp
extern std::vector <actor> actors;
actor::actor(int x, int y)
{
actor::x = x;
actor::y = y;
actors.push_back(*this);
}
该行:
actor (2, 3)
实际上创建了一个actor的实例,而不是被推送到actor矢量的那个?
注意:如果代码无法编译,请忽略任何错误。实际的代码确实编译了,但实际上粘贴在这里太复杂了。
答案 0 :(得分:5)
该行:
actor (2, 3)
实际上创建了一个actor的实例,而不是被推送到actor矢量的那个?
是。 actor(2, 3)
将创建类型为actor
的临时对象,除非它是未评估 1 的表达式的一部分。在这个临时的构造函数中,一个副本(*this
)将被压入堆栈(但请注意,在未评估的表达式中,构造函数当然不会被调用)。
在包含actor(2, 3)
的表达式的末尾,临时将被销毁。矢量副本将保持不变。
1 未评估的表达式是sizeof(…)
,typeid(…)
,decltype(…)
或noexcept(…)
表达式中的表达式。
答案 1 :(得分:4)
它在表达的评估期间保持“活着”,它是其中的一部分,并且会立即自动处理。
示例:
actor(2,3); // created and immediately destroyed
actor(2,3)->act(); // created, then acts, then destroyed
std::cout << actor(2,3) << std::endl; // created, streamed, destroyed
Gotcha(从不这样做)
actor const& shoot_myself(actor const& a) { return a; }
...
actor const& a = shoot_myself(actor(2,));
a->act(); // "segmentation fault / core dumped"
答案 2 :(得分:2)
您忘记在声明的末尾添加分号
actor (2, 3)
必须有
actor(2, 3);
当控件传递给下一个语句时,在此行中创建的临时对象将在同一行中删除。它的副本(对象的副本)将由向量中的构造函数推送。
结果,您将只有一个类型为actor的对象位于向量中。
如果要定义由此对象初始化的const引用,则可以保留临时对象。例如
const actor &ar = actor( 2, 3 );
在这种情况下,你有两个类型为actor的对象,它们将被推送到向量中,这个临时对象将由const引用引用。
这是一个展示所说内容的例子。
#include <iostream>
#include <vector>
struct A
{
int x, y;
A (int, int);
};
std::vector<A> v;
A::A( int x, int y ) : x( x ), y( y )
{
v.push_back( *this );
}
int main()
{
const A &ra = A( 2, 3 );
std::cout << "ra.x = " << ra.x << ", ra.y = " << ra.y << std::endl;
std::cout << "v[0].x = " << v[0].x << ", v[0].y = " << v[0].y << std::endl;
return 0;
}
输出
ra.x = 2, ra.y = 3
v[0].x = 2, v[0].y = 3
在此示例中,程序输出两个不同对象的值。