C++ 在哪些情况下根本没有构造函数,甚至没有默认构造函数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7131983/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 16:30:09  来源:igfitidea点击:

In which cases there is no constructor at all, even a default constructor?

c++constructordefault-constructor

提问by Samaursa

In this bookI am currently reading I ran across this:

在我目前正在阅读的这本书中,我遇到了这个:

A class doesn't need a constructor. A default constructor is not needed if the object doesn't need initialization.

一个类不需要构造函数。如果对象不需要初始化,则不需要默认构造函数。

Am I correct in inferring from the above that the compiler does not generate a default constructor for the class/structure in some cases? If yes, what are those cases? I will venture and say POD is probably one. Are there any other?

从上面推断编译器在某些情况下不会为类/结构生成默认构造函数是否正确?如果是,这些情况是什么?我敢说 POD 可能就是其中之一。还有其他的吗?

EDIT:I have changed the title as the original title gave the meaning that I asked when was a default constructor not defined instead of asking when does a class not have a constructor at all.

编辑:我已经更改了标题,因为原始标题给出了我询问何时未定义默认构造函数的含义,而不是询问何时一个类根本没有构造函数。

采纳答案by David Hammen

A class doesn't need a constructor. A default constructor is not needed if the object doesn't need initialization.

一个类不需要构造函数。如果对象不需要初始化,则不需要默认构造函数。

I think the author is talking about this situation:

我认为作者是在谈论这种情况:

some_type some_function () {
   POD_type this_is_intentionally_uninitialized;
   ...
}

Under some circumstances a constructor won't be called, period. As soon as you write a constructor you don't have a POD class, so now the constructor will be called.

在某些情况下,不会调用构造函数。一旦你编写了一个构造函数,你就没有 POD 类,所以现在将调用构造函数。

Whether it is a good or bad thing to have an object running around that contains random, uninitialized data is a different question entirely.

让一个包含随机、未初始化数据的对象到处跑是好事还是坏事完全是一个不同的问题。

回答by Johannes Schaub - litb

A default constructor is always declared. But it is not always defined. Only if it is used, then the compiler (or you) define it. Examples:

始终声明默认构造函数。但它并不总是被定义。仅当使用它时,编译器(或您)才定义它。例子:

struct A { std::string str; };
// not yet defined

struct B : A { };
// not yet defined

B b; 
// Now B::B and A::A are defined

Note that this has direct practical consequences

请注意,这具有直接的实际后果

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

回答by Alok Save

If you always create objects of an class using a constructor with parameters it won't need the default constructor.

如果您总是使用带参数的构造函数创建类的对象,则不需要默认构造函数。

The compiler generates a default constructor for every class, but if you define your own constructor for that class then the compiler does not generate a default constructor by itself. As long as you create objects of such an class through the constructor you provided, the class won't need and have a default constructor.

编译器为每个类生成一个默认构造函数,但如果您为该类定义自己的构造函数,那么编译器不会自行生成默认构造函数。只要您通过您提供的构造函数创建此类的对象,该类就不需要并具有默认构造函数。

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;
}

In context of the above example, consider the quote from the book:

在上述示例的上下文中,请考虑书中的引用:

A class doesn't need a constructor. A default constructor is not needed if the object doesn't need initialization.

一个类不需要构造函数。如果对象不需要初始化,则不需要默认构造函数。

In the above example as long as the object of Myclassis created in using #1, the class does not require and have a default constructor.

在上面的示例中,只要Myclass使用 #1 创建的对象,该类就不需要并且具有默认构造函数。

The default constructor needs to be defined for the class, if object of Myclassis created in a way which needs the default constructor, i.e: #2.

如果Myclass以需要默认构造函数的方式创建对象,则需要为类定义默认构造函数,即:#2。

回答by Matteo Italia

In my opinion, that sentence means that you don't always have to write your own default constructor, since some classes may not need to be initialized by default.

在我看来,这句话意味着您不必总是编写自己的默认构造函数,因为某些类可能不需要默认初始化。

For example, if your class contains several class fields that provide their own default constructor you don't need to write any default constructor, since the members' constructor is called anyway by default.

例如,如果您的类包含多个提供它们自己的默认构造函数的类字段,则您不需要编写任何默认构造函数,因为默认情况下无论如何都会调用成员的构造函数。

At the extreme opposite, you may want to write a structor a classof PODs for which you rely on the programmer to initialize correctly its fields manually; in this case, you may not write a default constructor, so the compiler will write its own that will leave these fields to their default uninitialized values (actually, it will be a no-op, and will probably be optimized away).

在极端情况下,您可能希望编写一个struct或多个classPOD,您依赖程序员手动正确初始化其字段;在这种情况下,您可能不会编写默认构造函数,因此编译器将编写自己的构造函数,将这些字段保留为默认的未初始化值(实际上,这将是一个空操作,并且可能会被优化掉)。

回答by Frigo

The compiler only declares and defines an automatically generated default constructor if you haven't provided any constructor.

如果您没有提供任何构造函数,编译器只会声明和定义一个自动生成的默认构造函数。

With a non-instantiable parent classhowever, it is possible to prevent any kind of constructor from working. By adding a dummy constructor with a dummy parameter, it is possible to kill only the automatically generated default constructor, at the expense of more red tape.

然而,对于不可实例化的父类,可以阻止任何类型的构造函数工作。通过添加一个带有虚拟参数的虚拟构造函数,可以只杀死自动生成的默认构造函数,代价是更多的繁文缛节。

回答by AnT

There's certain ambiguity in your question. You see, the implicit actions that the compiler takes with regard to constructors involve both declaringthem and definingthem. If some constructor is declared but not defined, do you consider it exists or not?

你的问题有一定的歧义。您会看到,编译器对构造函数采取的隐式操作包括声明它们和定义它们。如果某个构造函数已声明但未定义,您认为它是否存在?

Anyway, there's no way to create a class that has no constructors declaredfor it. The copy constructor, for one example, is always declared. There's no way to suppress it. If you don't declare it yourself, the compiler will declare it for you.

无论如何,没有办法创建一个没有为其声明构造函数的类。例如,复制构造函数总是被声明的。没有办法压制它。如果你不自己声明,编译器会为你声明。

As for the default constructor - it is possible to suppress its implicit declaration. If you declare anyconstructor yourself (i.e. explicitly), the compiler will not implicitly declare the default one. But in this case your class will, of course, have a constructor: the one that you declared yourself. (Plus, as I said above, the copy constructor is always declared).

至于默认构造函数 - 可以取消其隐式声明。如果您自己声明任何构造函数(即显式),编译器将不会隐式声明默认构造函数。但是在这种情况下,您的类当然会有一个构造函数:您自己声明的构造函数。(另外,正如我上面所说,复制构造函数总是被声明的)。

As for implicitly definedconstructors... They are defined by the compiler only if you use them. And, of course, they are defined only if it is possible. (If you use an implicit constructor, and it proves to be impossible to define, then your program simply will not compile).

至于隐式定义的构造函数……只有当你使用它们时,它们才由编译器定义。而且,当然,只有在可能的情况下才定义它们。(如果您使用隐式构造函数,并且证明无法定义,那么您的程序将无法编译)。

So, once again, when it comes to declaredconstructors, it is not possible to have a class with no constructors at all. Any class has at least one constructor declared for it.

所以,再一次,当涉及到声明的构造函数时,根本不可能有一个没有构造函数的类。任何类都至少声明了一个构造函数。

If your are interested in definedconstructors specifically, then it is indeed possible to have a class, for which no constructor is defined. Here's an example for you

如果您对定义的构造函数特别感兴趣,那么确实可能有一个没有定义构造函数的类。这是一个例子给你

struct S {
  S(const S&);
};

That's it. The class has one constructor declared it in, but it is not defined :)

就是这样。该类有一个构造函数声明它,但它没有定义:)

回答by Peter

A default constructor is not defined for a class if another constructor is declared.

如果声明了另一个构造函数,则不会为类定义默认构造函数。

For POD types (in the sense of being both trivial and standard-layout, as those terms are defined in C++11) it is a moot point whether the compiler generates a constructor or not, since the compiler-generated constructors are trivial. For gory details, have a look at What are Aggregates and PODs and how/why are they special?

对于 POD 类型(在平凡和标准布局的意义上,因为这些术语在 C++11 中定义),编译器是否生成构造函数是一个有争议的问题,因为编译器生成的构造函数是平凡的。有关详细信息,请查看什么是聚合和 POD 以及它们如何/为什么特别?

回答by Abhishek Maheshwari

So simply put - (in context of CPP) If not Constructor is defined, then compiler doesnt have default constructor. It is defined by the compiler only if it is required.

所以简单地说 - (在 CPP 的上下文中)如果没有定义构造函数,那么编译器没有默认构造函数。只有在需要时才由编译器定义。

There are certain cases where it is being done by the compiler. Some of which are -

在某些情况下,它是由编译器完成的。其中一些是——

  1. When we have a class which has a base class object as member( and derived class constructor is not defined). In this case the default contructor for derived class is created because the prolog of its contructor needs to call the base class contructor.
  2. We have a container object. Below code explains this.

    class Legs
    {
    ctor(); // ctor stands for constructor
    };
    class cat
    {
    Legs leg;
    public:
    cat(){}
    };
    
  3. In case of Virtual functions, the setting of Virtual table pointer to the correct V-Table is done in Constructor. For this reason also, the default constructor will be defined by the compiler.

  1. 当我们有一个具有基类对象作为成员的类时(并且未定义派生类构造函数)。在这种情况下,会创建派生类的默认构造函数,因为其构造函数的序言需要调用基类构造函数。
  2. 我们有一个容器对象。下面的代码解释了这一点。

    class Legs
    {
    ctor(); // ctor stands for constructor
    };
    class cat
    {
    Legs leg;
    public:
    cat(){}
    };
    
  3. 在虚拟函数的情况下,在构造函数中设置虚拟表指针到正确的 V 表。出于这个原因,默认构造函数将由编译器定义。

回答by Avinash

some_type some_function () { POD_type this_is_intentionally_uninitialized; ... }

some_type some_function () { POD_type this_is_intentionally_uninitialized; ... }