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