是否不需要默认生成的构造函数来构造所有基类?

用户名

我遇到过一种情况,其中类型安全的c ++会生成不匹配的ctor / dtor。以下代码为A生成两个构造函数。默认构造函数也构造其基数(B),但是默认生成的复制/移动ctor不会构造B。后来,它破坏了B,因此我们得到了不匹配的ctor / dtor。

我已经用gcc和clang尝试过了,但都失败了。在gcc错误报告论坛中,他们建议这不是gcc问题。我可能会遗漏一些东西,但是当类型安全代码导致对尚未构造的类的dtor调用时,这不是很奇怪吗?

程序输出:

B() -> INSERT: 0x7fff55398b2f
~B() -> ERASE: 0x7fff55398b2f
~B() -> ERASE: 0x7fff55398b40         // <- unmatched dtor call 
Assertion failed: (!all.empty()), function ~B, file gcc_bug.c, line 20.

代码如下:

#include <set>
#include <iostream>
#include <cstdint>
#include <cassert>
#include <experimental/optional>


std::set<std::uintptr_t> all;

struct B
{
    B()
    {
        std::cerr << "B() -> INSERT: " << this << "\n";
        all.insert((std::uintptr_t)this);
    }
    ~B()
    {
        std::cerr << "~B() -> ERASE: " << this << "\n";
        assert(!all.empty());                                // FAILS
        assert(all.find((std::uintptr_t)this) != all.end()); // FAILS
        all.erase((std::uintptr_t)this);
    }
};
struct A : B {};

static std::experimental::optional<A> f()
{
    A a;
    return a;
}

int main()
{
    auto a = f();
    return 0;
}
md5i

您有一个B由隐式定义的副本构造函数创建的对象。当然,这不是在打电话B::B()如果添加以下构造函数:

B(const B& other) : B()
{
    *this = other;
}

您将看到输出:

B() -> INSERT: 0x7ffe57ef918f
B() -> INSERT: 0x7ffe57ef91b0
~B() -> ERASE: 0x7ffe57ef918f
~B() -> ERASE: 0x7ffe57ef91b0

要带走的重要一点是:每个构造函数都完全构造对象。默认情况下,复制构造函数不会调用默认构造函数(显然,反之亦然)。因此,如果您需要在每个构造函数中执行某些操作,则必须在每个构造函数中通过直接调用或构造函数链接来明确地执行该操作。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么类需要默认构造函数,而结构却不需要?

来自分类Dev

std :: throw_with_nested是否需要Exception的虚拟基类的默认构造函数?

来自分类Dev

为什么复制构造函数不需要检查输入对象是否指向自身?

来自分类Dev

DdlGenerator构造函数不需要参数吗?

来自分类Dev

不需要no-arg构造函数的JPA实现

来自分类Dev

Spring在构造函数中不需要的属性?

来自分类Dev

C ++构造函数中不需要的隐式转换

来自分类Dev

不需要使用C ++复制构造函数

来自分类Dev

std :: variant在gcc 8和9中需要默认构造函数,而在gcc 10 / clang中则不需要

来自分类Dev

是否可以编写可变参数模板构造函数来初始化类/结构的所有成员?

来自分类Dev

编译器何时将默认生成的构造函数标记为noexcept?

来自分类Dev

不需要定义基类析构函数吗?

来自分类Dev

不需要定义基类析构函数吗?

来自分类Dev

ReactJS组件类是否需要构造函数

来自分类Dev

复制构造函数是否调用默认构造函数来创建对象

来自分类Dev

默认构造函数没有生成?

来自分类Dev

没有默认构造函数的类的向量

来自分类Dev

没有默认构造函数的 Java 类

来自分类Dev

在仅具有需要参数的已定义构造函数的类中调用默认构造函数(在Java中)

来自分类Dev

从Java类获取构造,将被调用的参数类型,不需要精确的参数与参数类型匹配

来自分类Dev

是否有可能在派生类构造函数中捕获从基类构造函数抛出的异常

来自分类Dev

为什么不需要在构造函数中指定变量?

来自分类Dev

为什么map的元素不需要复制或移动构造函数,而vector呢?

来自分类Dev

C ++类是否具有默认构造函数?在以下情况下会调用什么构造函数?

来自分类Dev

虚拟继承是否会强制基类默认可构造?

来自分类Dev

在Java中使用CDI时是否需要默认构造函数?

来自分类Dev

实现Externalizable时是否需要显式的默认构造函数?

来自分类Dev

C ++继承:避免调用基类的默认构造函数

来自分类Dev

如果构造不需要括号,该怎么办?

Related 相关文章

  1. 1

    为什么类需要默认构造函数,而结构却不需要?

  2. 2

    std :: throw_with_nested是否需要Exception的虚拟基类的默认构造函数?

  3. 3

    为什么复制构造函数不需要检查输入对象是否指向自身?

  4. 4

    DdlGenerator构造函数不需要参数吗?

  5. 5

    不需要no-arg构造函数的JPA实现

  6. 6

    Spring在构造函数中不需要的属性?

  7. 7

    C ++构造函数中不需要的隐式转换

  8. 8

    不需要使用C ++复制构造函数

  9. 9

    std :: variant在gcc 8和9中需要默认构造函数,而在gcc 10 / clang中则不需要

  10. 10

    是否可以编写可变参数模板构造函数来初始化类/结构的所有成员?

  11. 11

    编译器何时将默认生成的构造函数标记为noexcept?

  12. 12

    不需要定义基类析构函数吗?

  13. 13

    不需要定义基类析构函数吗?

  14. 14

    ReactJS组件类是否需要构造函数

  15. 15

    复制构造函数是否调用默认构造函数来创建对象

  16. 16

    默认构造函数没有生成?

  17. 17

    没有默认构造函数的类的向量

  18. 18

    没有默认构造函数的 Java 类

  19. 19

    在仅具有需要参数的已定义构造函数的类中调用默认构造函数(在Java中)

  20. 20

    从Java类获取构造,将被调用的参数类型,不需要精确的参数与参数类型匹配

  21. 21

    是否有可能在派生类构造函数中捕获从基类构造函数抛出的异常

  22. 22

    为什么不需要在构造函数中指定变量?

  23. 23

    为什么map的元素不需要复制或移动构造函数,而vector呢?

  24. 24

    C ++类是否具有默认构造函数?在以下情况下会调用什么构造函数?

  25. 25

    虚拟继承是否会强制基类默认可构造?

  26. 26

    在Java中使用CDI时是否需要默认构造函数?

  27. 27

    实现Externalizable时是否需要显式的默认构造函数?

  28. 28

    C ++继承:避免调用基类的默认构造函数

  29. 29

    如果构造不需要括号,该怎么办?

热门标签

归档