在我this book正在阅读的内容中,我遇到了这个问题:
一个类不需要构造函数。如果对象不需要初始化,则不需要默认构造函数。
我是否正确地从上面推断出编译器在某些情况下不会为类/结构生成默认构造函数?如果是,那些案件是什么?我会冒险说POD可能就是其中之一。还有其他吗?
编辑:我更改了标题,因为原始标题的含义是我询问何时是未定义的默认构造函数,而不是询问类何时根本没有构造函数。
答案 0 :(得分:5)
始终声明默认构造函数。但它并不总是被定义。只有在使用它时,编译器(或您)才能定义它。例子:
struct A { std::string str; };
// not yet defined
struct B : A { };
// not yet defined
B b;
// Now B::B and A::A are defined
请注意,这会产生直接的实际后果
struct A { private: A(); };
struct B : A { };
// valid, as B::B is not yet defined
B b;
// now invalid, because B::B is defined and tries to call a
// private base class constructor
答案 1 :(得分:5)
一个类不需要构造函数。如果对象不需要初始化,则不需要默认构造函数。
我认为作者正在谈论这种情况:
some_type some_function () {
POD_type this_is_intentionally_uninitialized;
...
}
在某些情况下,不会调用构造函数,句点。一旦你编写了一个构造函数,就没有POD类,所以现在将调用构造函数。
让一个包含随机,未初始化数据的对象运行是好还是坏是完全不同的问题。
答案 2 :(得分:3)
如果始终使用带参数的构造函数创建类的对象,则不需要默认构造函数。
编译器为每个类生成一个默认构造函数,但是如果为该类定义自己的构造函数,则编译器本身不会生成默认构造函数。只要您通过您提供的构造函数创建此类的对象,该类就不需要并具有默认构造函数。
class Myclass
{
int m_i;
public:
Myclass(int i)
{
m_i = i;
}
};
int main()
{
Myclass obj1(10); // #1, uses overloaded constructor
Myclass obj2; //#2, Will generate compiler error of no matching constructor
return 0;
}
在上述示例的上下文中,请考虑本书中的引用:
一个类不需要构造函数。如果对象不需要初始化,则不需要默认构造函数。
在上面的示例中,只要使用#1创建Myclass
的对象,该类就不需要并具有默认构造函数。
如果Myclass
的对象是以需要默认构造函数的方式创建的,则需要为该类定义默认构造函数,即:#2。
答案 3 :(得分:0)
在我看来,这句话意味着你不必总是编写自己的默认构造函数,因为默认情况下可能不需要初始化某些类。
例如,如果您的类包含几个提供自己的默认构造函数的类字段,则不需要编写任何默认构造函数,因为默认情况下仍会调用成员的构造函数。
在极端相反的情况下,您可能希望编写一个struct
或class
个POD,您依赖程序员手动初始化其字段;在这种情况下,您可能不会编写默认构造函数,因此编译器将自己编写,将这些字段保留为其默认的未初始化值(实际上,它将是无操作,并且可能会被优化掉)。
答案 4 :(得分:0)
如果您没有提供任何构造函数,编译器只会声明并定义一个自动生成的默认构造函数。
然而,使用non-instantiable parent class,可以防止任何类型的构造函数工作。通过添加一个带有伪参数的伪构造函数,可以仅杀死自动生成的默认构造函数,但代价是更多的繁文缛节。
答案 5 :(得分:0)
你的问题有些含糊不清。您可以看到,编译器对构造函数采取的隐式操作涉及声明它们和定义它们。如果声明了某个构造函数但未定义,那么您认为它是否存在?
无论如何,没有办法创建一个没有构造函数声明的类。例如,始终声明复制构造函数。没有办法压制它。如果你没有自己声明,编译器会为你声明它。
对于默认构造函数 - 可以抑制其隐式声明。如果您自己声明任何构造函数(即显式),编译器将不会隐式声明默认构造函数。但是在这种情况下,你的类当然会有一个构造函数:你自己声明的构造函数。 (另外,正如我上面所说,总是声明复制构造函数。)
至于隐式定义的构造函数......它们仅在您使用它们时由编译器定义。当然,只有在可能的情况下才会定义它们。 (如果使用隐式构造函数,并且证明无法定义,那么您的程序将无法编译)。
因此,再一次,当谈到声明的构造函数时,不可能有一个没有构造函数的类。任何类都至少为它声明了一个构造函数。
如果您对定义的构造函数特别感兴趣,那么确实可以有一个类,没有定义构造函数。这是你的一个例子
struct S {
S(const S&);
};
就是这样。该类有一个构造函数声明它,但它没有定义:)
答案 6 :(得分:0)
如果声明了另一个构造函数,则没有为类定义默认构造函数。
对于POD类型(在平凡布局和标准布局的意义上,这些术语在C ++ 11中定义),编译器是否生成构造函数是一个没有问题的,因为编译器生成的构造函数是微不足道的。有关血腥的详细信息,请查看What are Aggregates and PODs and how/why are they special?
答案 7 :(得分:0)
如此简单地说 - (在CPP的背景下) 如果没有定义构造函数,那么编译器没有默认构造函数。 它仅在需要时由编译器定义。
在某些情况下,编译器会执行此操作。其中一些是 -
我们有一个容器对象。下面的代码解释了这一点。
class Legs
{
ctor(); // ctor stands for constructor
};
class cat
{
Legs leg;
public:
cat(){}
};
如果是虚函数,则在构造函数中设置指向正确V表的虚拟表指针。出于这个原因,默认构造函数也将由编译器定义。
答案 8 :(得分:0)
some_type some_function(){ POD_type this_is_intentionally_uninitialized; ... }