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

发布于 2024-11-30 23:13:19 字数 321 浏览 1 评论 0原文

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

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

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

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

In this book I 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?

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

ぶ宁プ宁ぶ 2024-12-07 23:13:19

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

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

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

在某些情况下,不会调用构造函数,句号。一旦您编写了构造函数,您就没有 POD 类,因此现在将调用构造函数。

让一个包含随机、未初始化数据的对象运行是好是坏完全是另一个问题。

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.

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

抚笙 2024-12-07 23:13:19

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

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

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
不乱于心 2024-12-07 23:13:19

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

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

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

在上面的例子中,考虑一下书中的引用:

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

在上面的例子中,只要 Myclass 的对象是在 using #1 中创建的,该类就不需要并且有一个默认的构造函数。

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

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 Myclass is created in using #1, the class does not require and have a default constructor.

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

夜司空 2024-12-07 23:13:19

简而言之 - (在 CPP 的背景下)
如果没有定义构造函数,则编译器没有默认构造函数。
仅当需要时才由编译器定义。

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

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

    腿部类
    {
    构造函数(); // ctor代表构造函数
    };
    类猫
    {
    腿 腿;
    民众:
    猫(){}
    };
    
  3. 对于虚函数,将虚表指针设置为正确的 V 表是在构造函数中完成的。也出于这个原因,编译器将定义默认构造函数。

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.

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.

风透绣罗衣 2024-12-07 23:13:19

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

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

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

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 struct or a class of 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).

善良天后 2024-12-07 23:13:19

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

然而,使用不可实例化的父类,可以防止任何类型的构造函数停止工作。通过添加带有虚拟参数的虚拟构造函数,可以仅终止自动生成的默认构造函数,但代价是更多的繁文缛节。

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

With a non-instantiable parent class however, 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.

两仪 2024-12-07 23:13:19

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

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

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

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

因此,再次强调,当涉及到声明的构造函数时,不可能有一个类根本没有构造函数。任何类都至少有一个为其声明的构造函数。

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

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

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

There's certain ambiguity in your question. You see, the implicit actions that the compiler takes with regard to constructors involve both declaring them and defining them. 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 declared for 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 any constructor 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 defined constructors... 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 declared constructors, 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 defined constructors 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 :)

哆兒滾 2024-12-07 23:13:19

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

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

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?

像你 2024-12-07 23:13:19

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文