【问题标题】:C++ Compiler background of construting objects [closed]构造对象的C ++编译器背景[关闭]
【发布时间】:2016-02-15 12:20:19
【问题描述】:

例如我有一行代码:

已编辑:

MyClass myObject = MyClass(5);

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

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

【问题讨论】:

  • 这个代码是非法的。您的其他示例列表中的代码也是如此。也许您的意思是 int i = 0; MyClass myObject = MyClass(i); 或其他什么。细节在这里实际上很重要。请返回您的编译器并检查您发布的代码是否实际上是您编译的代码
  • 编辑后您的代码仍然无效。我也不确定你的问题是什么。编译器知道要做什么,因为有一个标准,它可以控制分配的位置和时间。
  • 请问到底什么是无效的?另外,我发布这个问题是希望获得有关编译器功能和程序集的专业答案。例如答案可能在 operator= 等,但我仍然在问,因为我想知道它的实际行为。
  • 我现在对那些基础知识什么是什么以及如何编写代码不感兴趣。我对建筑和背景感兴趣。
  • “编译器功能和程序集”、“架构和背景”不是标准强制要求的;所需要的只是给定输入代码的可观察行为的某种结果。参考文档将解释该行为是什么,并可能建议实现它的典型方法。对于其他任何事情,告诉你的编译器输出 ASM 并自己阅读。

标签: c++ constructor compiler-construction


【解决方案1】:
MyClass myObject = MyClass( int i );

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

int i = 42;
MyClass myObject = MyClass( i );

这实际上等同于(*):

MyClass myObject( i );

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

myObject = new MyClass(int i);

同样,这是声明和使用语法的无效混合。您可能的意思是:

int i = 42;
MyClass * myObject = new MyClass( i );

这会分配动态存储空间(“在堆上”)并在那里构造一个MyClass 对象。

然后将指向该内存/对象的指针分配给myObject,其类型为pointerMyClass


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



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

1) 为什么MyClass myObject = MyClass(i); 这个其实相当于:MyClass myObject(i);

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

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

由于myObject -- 分配给 -- 的对象是由该语句创建的,并且在该语句之后临时将不存在,C++ 标准允许“临时”MyClass 对象将由构造函数(*)创建代替myObject,避免临时的构造/分配/销毁的重复工作。

(随着“移动”语义和&& 右值引用的出现,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);
}

这将打印:

const
dest

没有任务。

2) 在这种情况下,“=”是 operator=(重载)吗?

没有。正如我所说,该特定语句等同于MyClass myObject( i )——没有发生分配,只是就地构造。

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

我认为通过反汇编你不会学到很多东西。无论如何,你的编译器比我做得更好。 (或者你是。)

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

什么角色?我不明白你的意思。



(*):正如 rici 正确指出的那样,仅当存在可见的复制/移动构造函数时,copy elision 才能实现此等价物。

【讨论】:

  • 话虽如此,时间和地点来学习这一切的细则和细节,但从你的问题来看,我怀疑你应该现在坚持“它只是工作”。学习正确的语法,只需使用语言给你的东西。首先学习驾驶汽车,了解“离合器”和“变速箱”的实际作用,然后再尝试了解它们的实际工作原理 .无意冒犯,但你现在在驾校;不要试图拆除一切。 ;-)
  • 我被误解了。我已经使用嵌入式系统工作了几年。此外,我正在深入研究 ARM 架构和软件工具链规范和功能。我在 C 程序方面有很强的背景。现在我进入了 C++。当我有空闲时间时,我会尝试更深入地理解它,而不仅仅是“它只是工作”。我讨厌人们的态度是这样的。我真的很讨厌它。我的问题比 DevSolar 的这个答案要深得多。我的错误是急着发帖而不是检查我是否在代码中犯了那个简单的愚蠢错误,这导致了这个讨论。
  • @KarolisMilieška:那么请改进你的问题,以便我改进我的答案。就目前而言,除了我在回答中写的内容之外,很难说出您想知道的内容。我讨厌这种态度,我真的很讨厌这种态度,当人们不费心写一个问题,然后抱怨他们的回答 /i> 问题不令人满意,因为我的水晶球阅读技巧未能正确判断您的经验、技能组合、和实际问题
  • @DevSolar - 我不明白你为什么将 MyClass( int i ) 称为 copy 构造函数而不是常规构造函数 - copy constructors 引用另一个完全实例化的对象相同的类型并复制它,并且通常具有例如 MyClass( const MyClass&amp; src) 的语法。
  • @DevSolar:MyClass myObject = MyClass(i);MyClass myObject(i);相当。由于复制省略,它们最终都做了同样的事情,但第一个不会编译,除非有公共复制或移动构造函数。 (因为您无法忽略非法副本。)
猜你喜欢
  • 2013-09-05
  • 1970-01-01
  • 2016-12-23
  • 2010-09-12
  • 1970-01-01
  • 2010-09-18
  • 1970-01-01
  • 1970-01-01
  • 2013-02-12
相关资源
最近更新 更多