C++ C++;构造对象的编译器背景

C++ C++;构造对象的编译器背景,c++,constructor,compiler-construction,C++,Constructor,Compiler Construction,例如,我有一行代码: 编辑: MyClass myObject = MyClass(5); 在这里,将调用MyClass MyClass()的构造函数。它接受参数并执行所需的操作。。 但我认为这个示例myObject不是一个引用-它是一个实际的对象。那么编译器是如何做到这一点的: 用MyClass构造函数构造一个对象,它不知道实际对象的位置 (我所说的位置是指堆栈上RAM中的地址)。 同样的问题也适用于其他示例(myObject=newmyclass(5);,myObject(5),等等) 编

例如,我有一行代码:

编辑:

MyClass myObject = MyClass(5);
在这里,将调用MyClass MyClass()的构造函数。它接受参数并执行所需的操作。。 但我认为这个示例myObject不是一个引用-它是一个实际的对象。那么编译器是如何做到这一点的: 用MyClass构造函数构造一个对象,它不知道实际对象的位置 (我所说的位置是指堆栈上RAM中的地址)。 同样的问题也适用于其他示例(myObject=newmyclass(5);,myObject(5),等等)

编辑
1) 为什么
MyClass myObject=MyClass(i)
这实际上相当于:
MyClass myObject(i)
2) 在这种情况下,“=”是运算符=(重载)?
3) 能否为编译器生成的操作编写等效代码?
4) 复制构造函数在这里扮演什么角色(
MyClass myObject=MyClass(i);

这是一个语法错误,是声明和使用的非法混合。你可能是说:

int i = 42;
MyClass myObject = MyClass( i );
int i = 42;
MyClass * myObject = new MyClass( i );
这实际上相当于(*):

这将声明一个具有本地作用域(“在堆栈上”)的
MyClass
对象,然后使用
MyClass
构造函数初始化内存

myObject = new MyClass(int i);
同样,这是声明和使用语法的无效混合。你可能是说:

int i = 42;
MyClass myObject = MyClass( i );
int i = 42;
MyClass * myObject = new MyClass( i );
这将分配动态存储(“在堆上”),并在那里构造一个
MyClass
对象

然后将指向该内存/对象的指针指定给
myObject
,该指针属于指向
MyClass
的指针类型


在这两种情况下,构造函数都会在{some memory location}处初始化
MyClass
对象。哪个位置取决于调用构造函数的上下文。编译器知道该上下文,并且知道(如何获得)运行时的内存地址



回答添加的问题(实际上应该是单独的问题):

1) 为什么
MyClass myObject=MyClass(i)这实际上相当于:
MyClass myObject(i)

这个看起来像一个构造函数调用,创建了一个临时的
MyClass
对象,然后将该对象(
operator=()
)分配给
myObject

但事实并非如此,因为那样做太愚蠢了

自从MyObjult/Cuff>——被分配的对象是由这个语句创建的,并且在该语句之后不存在临时性,C++标准允许“临时”<代码> MyClass < /C>对象由构造函数(*)代替<代码> MyObjult<代码>。避免施工/分配/销毁临时设施的重复工作

(某种程度上,随着“移动”语义和
&
右值引用的出现,C++11扩展到任何类型的临时变量的机制。)

考虑:

#include <iostream>

class MyClass
{
    public:
        MyClass( int i ) : member( i ) { std::cout << "const\n"; }
        ~MyClass() { std::cout << "dest\n"; }
        MyClass & operator=( MyClass const & other ) { std::cout << "assign\n"; }

    private:
        int member;
};

int main()
{
    MyClass x = MyClass(42);
}
没有任务

2) 在这种情况下,“=”是运算符=(重载)

不。正如我所说,这个特定语句相当于MyClass myObject(I)
——没有赋值,只是就地构造

3) 您能为编译器生成的操作编写等效代码吗

我认为你不会从拆卸中学到什么。不管怎样,你的编译器在这方面比我强。(或者你是。)

4) 复制构造函数在这里扮演什么角色(MyClass myObject=MyClass(i);)

什么角色?我不知道你的意思




(*):正如rici正确指出的那样,只有在存在可见的复制/移动构造函数的情况下,创建此等效项才是合法的。

此代码是非法的。其他示例列表中的代码也是如此。也许你的意思是
inti=0;MyClass myObject=MyClass(i),或者别的什么。这里的细节其实很重要。请返回您的编译器,检查您发布的代码是否确实是您编辑后编译的代码。您的代码仍然无效。我也不知道你的问题是什么。编译器知道该做什么,因为有一个标准,它控制着它在何时何地分配东西。那么我可以问一下什么是无效的吗?另外,我发布这个问题是希望得到关于编译器特性和汇编的专业答案。例如,答案可能是operator=等,但我仍然在问,因为我想知道它的实际行为。我现在对这些基础知识不感兴趣什么是什么以及如何编写代码。我对体系结构和背景感兴趣。“编译器特性和汇编”,“体系结构和背景”不受标准的约束;所需要的只是给定输入代码的可观察行为的特定结果。参考文档将解释该行为是什么,并可能建议实施该行为的典型方法。对于其他任何事情,请告诉编译器输出ASM并自己阅读。尽管如此,学习所有这些细节和细节是有时间和地点的,但是从你的问题来看,我怀疑你现在应该坚持“它只是工作”。学习正确的语法,只需使用语言所提供的内容。首先学习驾驶汽车,以及“离合器”和“变速箱”的实际功能,然后再尝试了解它们的实际工作原理。无意冒犯,但你现在在驾驶学校;不要试图拆除所有东西。;-)我被误解了。我在嵌入式系统领域工作了两年。此外,我还在深入研究ARM体系结构和软件工具链规范和特性。我有很强的C程序背景。现在我进入C++了。当我有空的时候,我试着去理解它,而不仅仅是“它只是工作”。我讨厌人们的态度是这样。我真的很讨厌它。我的问题比DevSolar的回答要深刻得多。我的错误是匆忙发帖,没有检查我在代码中是否犯了那个简单愚蠢的错误,这导致了这次讨论。@KarolisMilieška:那么请改进
const
dest