当前位置: 首页 > 知识库问答 >
问题:

为什么C++中类字段的默认初始化需要调用析构函数?

李良策
2023-03-14

请帮我做这个程序:

struct U { 
    U(int *) noexcept;
private:
    ~U() noexcept;
};

struct B {
    B();
    ~B();
    U v; //ok
    U w{nullptr}; //ok
    U u = nullptr; //error
};

这里,structu有一个私有析构函数,只是为了演示析构函数不是由编译器真正调用的,并简化代码的长度。

error: 'U::~U()' is private within this context
   13 |     U u = nullptr; //error

问题是:

  1. 如果b::b()不在此转换单元中编译,为什么要考虑字段默认初始化?
  2. 出现错误是因为为初始化u字段创建了临时对象吗?(没有强制删除副本?)
  3. 那么UW情况有什么不同?

共有1个答案

长孙淳
2023-03-14

如果B::B()没有在这个翻译单元中编译,为什么要考虑字段默认初始化?

因为成员初始化是类定义的一部分。因此,类定义本身是无效的,而不必涉及其构造函数的定义。在标准中,您可以从[class.mem.general]开始,一直到brace-or-equal-initializer,这最终需要一个有效的“bog-standard”赋值表达式。

错误是因为为u字段的初始化创建了一个临时对象吗?(没有强制删除副本?)

<source>:13:11: error: temporary of type 'U' has private destructor
    U u = nullptr; //error

W是直接初始化的,而不需要事先创建临时的,因此创建它可以很好地工作,因为表达式中没有任何内容试图调用U的析构函数。显然,B::~B()的任何定义在W上仍然会失败,但这超出了重点。

 类似资料:
  • 问题内容: 默认构造函数和直接初始化对象的字段之间有什么区别? 有什么原因要偏爱以下示例之一? 例子1 例子2 问题答案: 初始化程序在构造函数主体之前执行。(如果你同时具有初始化程序和构造函数,则会产生影响,构造函数代码将第二次执行并覆盖初始化值) 当你始终需要相同的初始值(例如,在你的示例中为给定大小的数组或特定值的整数)时,初始化器是很好的选择,但是它可以对你有利或不利于你: 如果你有许多构

  • 如果我在我的类中创建一个bool,就像一样,它默认为false。 当我在我的方法中创建相同的bool时,我得到一个错误“使用未分配的局部变量检查”。为什么?

  • 如果我有一个struct Foo和一个struct Bar: 如果我初始化一个条并打印正确得到的值: 但是现在如果我声明这样的构造函数: 我失去了Bar::foo的默认构造,程序输出了32764 0 5! 为什么我不得不像这样无声地初始化每个成员变量: 只要我声明一个构造函数?在这种情况下,为什么默认构造不起作用?

  • 问题内容: 所以我要声明并初始化一个int数组: 说我改为这样做… … 0将按标准输出。另外,如果我这样做: 将按标准输出。那么默认如何初始化我的数组?是否可以安全地假设默认的初始化将数组索引设置为零,这意味着我不必遍历数组并对其进行初始化? 问题答案: Java程序中未由程序员明确设置为所有内容的所有内容都初始化为零值。 对于的引用(任何包含对象的内容)。 对于int / short / byt

  • 这是一个关于java中子类的非常基本的问题,我还是不明白…… 假设我有一个超类,它有三个字段,并且只有默认的构造函数: 我想添加一个字段x。我无法更改,所以我创建了一个子类: 我现在想从现有的对象生成object: 这样我仍然可以访问,等。 如果不在子类的构造函数中“手动”分配所有这些字段,我如何才能最好地做到这一点?

  • 我正在创建一个带有片段的应用程序,在其中一个片段中,我创建了一个非默认构造函数,并收到以下警告: 有人能告诉我为什么这不是个好主意吗? 你能否建议我如何做到这一点: 不使用非默认构造函数?