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

C++ 如果我声明一个没有名字的类实例,它会留在内存中吗?,c++,class,vector,instance,member,C++,Class,Vector,Instance,Member,我有以下代码(我将跳过包含的内容和您拥有的内容): main.cpp std::vector <actor> actors; int main() { actor (2, 3); } actor.cpp extern std::vector <actor> actors; actor::actor(int x, int y) { actor::x = x; actor::y = y; actors.push_back(*this); }

我有以下代码(我将跳过包含的内容和您拥有的内容):

main.cpp

std::vector <actor> actors;
int main() {
    actor (2, 3);
}
actor.cpp

extern std::vector <actor> actors;
actor::actor(int x, int y)
{
    actor::x = x;
    actor::y = y;
    actors.push_back(*this);
}
除了被推送到actors向量的一个实例之外,实际上还创建了一个actor实例吗

注意:如果代码没有编译,请忽略任何错误。实际代码确实可以编译,但是太复杂了,无法真正粘贴到这里。

它在表达式求值期间保持“活动”,它是表达式的一部分,并在求值后立即自动处理

例如:

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
请问该行:

    actor (2, 3)
actor (2, 3)
除了被推送到actors向量的一个实例之外,实际上还创建了一个actor实例吗

actor(2,3)
将创建类型为
actor
的临时对象,除非它是未计算的表达式的一部分1。在这个临时表达式的构造函数中,(this)的一个副本将被推送到堆栈上(但再次注意,在未赋值表达式中,构造函数当然不会被调用)

在包含
actor(2,3)
的表达式末尾,临时变量将被销毁。矢量副本将保持不变



1未赋值表达式是(…)、
typeid(…)
decltype(…)
noexcept(…)
表达式中的表达式。

您忘记在语句末尾放置分号了

actor (2, 3)
一定有

actor(2, 3);
当控件传递给下一个语句时,此行中创建的临时对象将在同一行中删除。它的副本(对象的副本)将由向量中的构造函数推送

因此,向量中只有一个类型为actor的对象

如果要定义由该对象初始化的常量引用,则可以保留临时对象。比如说

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;
}

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

不清楚。OP的代码不编译,如果表达式是
sizeof(actor(2,3))
,则不会发生推送。没有人提到
sizeof
,OP只询问特定行
actor(2,3)
@KonradRudolph:关键是并不是每个表达式都会被计算,并且只有在计算发生时才会产生预期的副作用。我认为这是一个非常普遍的观点,值得一提。1的答案是唯一的C++答案,所以用一个有意义的方式“推到堆栈”这个短语。@ KerrekSB很有趣,因为它实际上是偶然的(我是说<代码>向量< /代码>)。p但是我会让它保持不变,因为它是准确的。作为对你笔记的回复:你的工作是制作一个最小的例子,它精确地展示了正在仔细研究的问题。如果实际的代码太复杂,请删减它,或者构建一个最小的编译示例。事实上,这是一个写得非常好的问题,“甚至在std::endl流媒体之前”——嗯。你确定吗?我当时的印象是(事实上,我现在仍然是!)这是错误的。子表达式的求值顺序完全未定义。(编辑:)@KonradRudolph-正确,尽管在我的示例中子表达式的顺序明显是从左到右,但我已经更新了答案
const actor &ar = actor( 2, 3 );
#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