如果我声明一个没有名字的类实例,它会留在内存中吗?

时间:2014-02-18 21:33:06

标签: c++ class vector instance member

我有以下代码(我将跳过包含和你有什么):

的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矢量的那个?

注意:如果代码无法编译,请忽略任何错误。实际的代码确实编译了,但实际上粘贴在这里太复杂了。

3 个答案:

答案 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

在此示例中,程序输出两个不同对象的值。