为什么编译器发出的 C++默认构造函数“不好”?
Could someone please explain what is meant by the following?
You must define a default constructor if your class defines member variables and has no other constructors. Otherwise the compiler will do it for you, badly.
What are they referring to as "badly"?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
从该链接的扩展:
From the expansion of that link:
可能会参考
new T
和new T()
当没有提供 ctor 时会有所不同。Might refer to how
new T
andnew T()
differ when there is no ctor provided.最好确保该对象是在已知状态下创建的。默认情况下,原始变量不会设置为零,因此您最终可能会遇到并不总是出现的微妙错误。通过将成员变量初始化为合理的变量,一切都变得更加可预测。
It's good to be sure that the object is created in a known state. Primitive variables won't be set to zero by default, so you could end up with subtle bugs that don't always show up. By initializing the member variables to sensible variables, everything is much more predictable.
默认构造函数的唯一问题是它只初始化编译器认为必须初始化的内容,而不初始化您可能认为需要初始化的内容。基本上,这意味着它将调用具有默认初始化程序的对象的初始化程序。它不会将指针或简单类型(例如
int
)设置为正常值等。如果这足够了,那么默认构造函数就不是“坏”的。当它不足时,这是一个错误(在您的代码中),因为您没有使用正确的初始化定义必要的默认构造函数。The only problem with the default constructor is that it initializes only what the compiler thinks must be initialized, and not what you may think needs to be initialized. Basically, that means that it will invoke initializers for objects with default initializers. It won't set pointers or simple types like
int
to sane values, etc. If that is sufficient, then the default constructor is not 'bad'. When it is insufficient, it is a bug (in your code) that you did not define the necessary default constructor with the correct initialization.对 Google 风格指南持保留态度——或者可能是一卡车盐。
确实,编译器生成的默认构造函数不一定会以有意义的方式初始化内置类型的成员。如果你希望做到这一点,那么是的,未能做到这一点是很糟糕的。 OTOH,如果您不想这样做,那么这样做也可能有点糟糕(浪费)。
底线:有时会编写自己的默认构造函数,但它们倾向于例外,而不是规则。尽管有一些简单的经验法则可以涵盖 C++ 中的许多情况并且可以防止许多问题,但这实际上不是其中之一 - 在这里您几乎确实需要知道什么是编译器生成的 ctor 会做,如果你要编写自己的 ctor,你想要的会有所不同。
Take the Google style guide with a grain of salt -- or maybe a truckload of salt.
It is true that the compiler-generated default constructor won't necessarily initialize members that are of built-in types in a meaningful fashion. If you want that done, then yes, its failure to do that is bad. OTOH, if you don't want that done, then its doing it could be somewhat bad (wasteful) as well.
Bottom line: there are times to write your own default ctor, but they tend toward the exception, not the rule. Although there are simple rules of thumb to cover a lot of cases in C++ and will prevent a lot of problems, this really isn't one of them -- here you pretty much do need to know what the compiler-generated ctor will do, and what you want different if you're going to write your own.
在调试构建中,大多数编译器会用一些神奇的值填充未初始化的空间,以便调试可靠。并且提供自定义构造函数会阻止某些 POD 优化。
In Debug build most compilers fill uninitialized space with some magic values, so that debugging is reliable. And providing custom constructor prevents certain POD optimizations.
事实上,它只是确保人们明确声明任何对象的无效或默认状态的指南。
这样,与实际执行相比,阅读代码时就不会感到惊讶了。
但是,请认为这是公司指南,用于确保每个人都遵循相同的规则,而不是因为谷歌这样做就必须遵循它。
事实上,如果您设法使所有成员对象在默认构造时处于有效状态,或者强制您设置构造函数,那么就没有充分的理由采用这样的准则。
In fact, it's a guideline just to make sure people does explicitely make the statement of what is an invalid or default state of any object.
That way, no surprise when reading the code, compared to the actual execution.
However, think that it's a company guideline, that is used to make sure everyone does follow the same rules, that's not a you-must-follow-it-because-google-does-it.
In fact, if you manage to make all your member objects being in valid state when default constructed, or force you to set a constructor, then there is no good reason for such a guideline.
如果您有任何原始类型作为成员变量(例如 int、float),则默认 ctor 将不会初始化它们。属于类类型的成员变量将调用其默认构造函数。
首选成员初始值设定项列表,因此您的用户提供的 ctor 可能为空:
If you have any primitive types as member variables (eg. int, float), then the default ctor will not initialize them. member variables that are a class type will have their default ctor's invoked.
Prefer member initializer lists, so your user supplied ctor may be empty:
它不会将整数设置为 0 或将指针设置为 null。它将在具有构造函数的类型的对象上运行默认构造函数。
有些人会称之为“不明智”。
It won't set integers to 0 or pointers to null. It will run default constructors on object of types with constructors.
Some people would call it 'not sensible'.
这似乎是 3 规则的过于简化的版本,您应该自己定义或保留
的编译器版本(请注意,通过定义自己的复制构造函数,编译器不会定义默认值构造函数)。
It just seems a too simplified version of the rules of 3, you should either define yourself or leave the compiler version of
(Note that by defining yourself a copy constructor, the compiler won't define a default constructor).
编译器构建的默认构造函数“什么都不做”,它甚至不会将对象占用的内存清零
The default constructor built by the compiler does 'nothing', it will not even zero the memory occupied by the object