空的构造函数总是在C ++中调用吗? [英] Are empty constructors always called in C++?

查看:161
本文介绍了空的构造函数总是在C ++中调用吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个一般的问题,这可能是一个小编译器特定。
我对调用构造函数的条件感兴趣。具体来说,在发布模式/针对速度优化的构建中,在实例化对象时,是否始终调用编译器生成的或空的构造函数?

I have a general question, that may be a little compiler-specific. I'm interested in the conditions under which a constructor will be called. Specifically, in release mode/builds optimised for speed, will a compiler-generated or empty constructor always be called when you instantiate an object?

class NoConstructor  
{  
    int member;  
};  

class EmptyConstructor  
{  
    int member;  
};

class InitConstructor  
{  
    InitConstructor()  
        : member(3)   
    {}  
    int member;  
};

int main(int argc, _TCHAR* argv[])  
{  
    NoConstructor* nc = new NoConstructor(); //will this call the generated constructor?  
    EmptyConstructor* ec = new EmptyConstructor(); //will this call the empty constructor?  
    InitConstructor* ic = new InitConstructor(); //this will call the defined constructor  

    EmptyConstructor* ecArray = new EmptyConstructor[100]; //is this any different?
}

我做了很多搜索,在Visual Studio中生成汇编代码。

I've done a lot of searching, and spent some time looking through the generated assembly code in Visual Studio. It can be difficult to follow in release builds though.

总之:
构造函数总是被调用吗?如果是,为什么?

In summary: Is the constructor always called? If so, why?

我明白这将非常依赖于编译器,但肯定有一个共同的立场。

I understand this will very much depend on the compiler, but surely there's a common stance. Any examples/sources you can cite would be really appreciated.

推荐答案

在优化模式下,如果你的类或结构是POD只有POD类型)和构造函数没有指定,任何生产质量的C ++编译器不仅会跳过对构造函数的调用,甚至不会生成它。

When in optimizing mode, if your class or structure is POD (has only POD types) and constructor is not specified, any production quality C++ compiler will not only skip the call to a constructor but not even generate it.

如果你的类有非POD成员的构造函数必须被调用,编译器将生成调用成员的构造函数的默认构造函数。但即使如此 - 它不会初始化POD类型。也就是说如果你不明确地初始化成员,那么你最终可能会有垃圾。

If your class has non-POD members who's constructor(s) have to be called, compiler will generate default constructor that calls member's constructors. But even then - it will not initialize POD types. I.e. if you don't initialize member explicitly, you may end up with garbage there.

如果你的编译器/链接器有LTO,甚至幻想。

The whole thing can get even fancies if your compiler/linker has LTO.

希望它有帮助!并使您的程序首先工作,然后使用分析器检测缓慢的地方,然后优化它。过早优化可能不仅使您的代码不可读,浪费了大量的时间,但也可能无济于事。

Hope it helps! And make your program work first, then use a profiler to detect slow places, then optimize it. Premature optimization may not only make your code unreadable and waste tons of your time, but could also not help at all. You have to know what to optimize first.

这里是你的例子中的代码反汇编(x86_64,gcc 4.4.5):

Here is a disassembly for code in your example (x86_64, gcc 4.4.5):

main:
    subq    $8, %rsp
    movl    $4, %edi
    call    _Znwm
    movl    $4, %edi
    movl    $0, (%rax)
    call    _Znwm
    movl    $4, %edi
    movl    $0, (%rax)
    call    _Znwm
    movl    $400, %edi
    movl    $3, (%rax)
    call    _Znam
    xorl    %eax, %eax
    addq    $8, %rsp
    ret

可以看到,没有构造函数被调用。没有类,每个对象只是一个4字节的整数。

As you can see, there are no constructors called at all. There are no classes at all, every object is just a 4 bytes integer.

使用MS编译器,YMMV。所以你必须自己检查拆卸。但结果应该类似。

With MS compiler, YMMV. So you have to check disassembly yourself. But result should be similar.

祝你好运!

这篇关于空的构造函数总是在C ++中调用吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆