C++ 如何使用隐藏的默认构造函数初始化成员?

马克斯·基兰

我有一个带有隐藏默认构造函数的类来强制使用带参数的构造函数。另一个类正在使用该类的 2 个实例:

typedef struct { ... } BAZ;

class Foo {
  private:
    Foo(void) {}

  public:
    Foo(BAZ a) { ... }
};

class Bar {
  private:
    Foo foo1;
    Foo foo2;

    Bar(void) {}

  public:
    Bar(BAZ a, BAZ b) : foo1(a), foo2(b) { ... }
};

最明显的是变量 foo1 和 foo2 的声明将调用默认的 Foo 构造函数,但由于它是私有的,因此不能并且会给出编译器错误。

有没有办法阻止它尝试默认的 Foo 构造函数,而只是等待 Bar 构造函数初始化它们?

我想避免使用new关键字(这将解决整个问题)。

编辑:
似乎人们很难理解这个问题和困境。我将尝试解释:

我想强制使用 Foo(BAZ) 构造函数,这意味着任何使用 Foo(void) 构造函数的尝试都会产生错误。

为了隐藏默认构造函数,它被声明为私有成员。如果有人尝试使用默认构造函数 Foo() ,它会产生故意错误。

不声明默认构造函数而只声明 Foo(BAZ) 不会阻止编译器创建公共默认构造函数。如果我声明它为 Foo(),它不会出错。到目前为止,它工作正常并符合预期。

第二个类 Bar 有两个 Foo 实例,但是当 Bar 被实例化时,这些 Foo 成员将使用默认(隐藏)构造函数调用并生成错误。然后在 Bar 构造函数中,这两个实例将使用正确的公共构造函数 Bar(BAZ a, BAZ b) 进行初始化:foo1(a), foo2(b)。这就是我要的。

有没有办法防止它在初始化 Bar 时调用 Foo 默认构造函数,以便 Bar 构造函数可以使用正确的 Foo 构造函数?

解决方案的工作,因为默认的构造函数永远不会被调用:

BAZ a = {...}
Foo *foo1 = new Foo(a);

我希望这能让它更清楚。

EDIT2:已解决错误不在隐藏的 Foo 构造函数中,而是隐藏的 Bar 构造函数试图使用隐藏的默认 Foo 构造函数。

Bar(void) : Foo(BAZ{}), Foo(BAZ{}) {}

解决了。

EDIT3:
真正的问题似乎出在开发工具中。重新启动并手动清除缓存后,它按照 C++14 标准的预期工作。

皮特·贝克尔

变量 foo1 和 foo2 的声明将调用默认的 Foo 构造函数

不。声明这些成员变量表示它们是成员。它没有说明它们将如何构建。这是使用它们的类的构造函数的工作。

Bar(BAZ a, BAZ b) : foo1(a), foo2(b) { ... }

到目前为止还好:这个构造函数使用构造函数构造foo1foo2成员Foo(Baz)

Bar(void) {}

这就是问题所在:它尝试使用 的默认构造函数构造foo1foo2成员Foo由于该构造函数不可访问(这是正确的术语;它不是hidden),因此您会收到错误消息。至少有以下三种解决方案:

1:

Bar() : foo1(Baz()), foo2(Baz()) {}

这使用了采用Baz.

2:

Bar() = delete;

这使得默认构造函数Bar不存在,因此它不会尝试使用默认构造函数 for Foo

3:

只是不要这样做。如果您没有编写默认构造函数但确实编写了另一个构造函数,则编译器将不会生成默认构造函数。

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

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

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何使用已删除的副本构造函数初始化类数组(C ++ 11)

来自分类Dev

使用构造函数初始化数组(C ++)

来自分类Dev

为什么就地成员初始化在C ++ 11中使用副本构造函数?

来自分类Dev

如何在C ++中使用构造函数初始化2D向量?

来自分类Dev

没有初始化列表的初始化成员变量和没有默认构造函数的类型?

来自分类Dev

使用默认默认构造函数的C ++ 11值初始化

来自分类Dev

C ++:初始化成员向量值

来自分类Dev

使用自定义构造函数作为Objective C类成员初始化C ++类的实例吗?

来自分类Dev

为什么显式声明的构造函数阻止使用C ++ 11初始化列表进行成员初始化?

来自分类Dev

C ++成员初始化和构造函数

来自分类Dev

C ++在构造函数初始化列表中获取类成员地址

来自分类Dev

如何在C ++中初始化成员的构造函数参数

来自分类Dev

用多个构造函数调用初始化成员变量

来自分类Dev

C ++构造函数如何初始化其类的对象?

来自分类Dev

如何在C ++中使用构造函数(只是构造函数)在类中初始化大型私有数组?

来自分类Dev

在使用相同名称的构造函数参数初始化成员变量时,=和{}之间的区别

来自分类Dev

C ++:在constexpr构造函数中初始化成员数组

来自分类Dev

C ++:具有初始化列表的默认构造函数

来自分类Dev

C ++初始化程序列表成员仍在调用默认构造函数?

来自分类Dev

在Dart中的可选参数构造函数中使用构造函数初始化成员

来自分类Dev

如何根据条件使用不同的构造函数初始化C ++参考?

来自分类Dev

如何在C ++中使用构造函数初始化2D向量?

来自分类Dev

为什么显式声明的构造函数阻止使用C ++ 11初始化列表进行成员初始化?

来自分类Dev

使用已删除的默认构造函数初始化成员

来自分类Dev

Matlab-构造函数不会初始化成员值

来自分类Dev

如何在Objective-C中使用自定义构造函数初始化自动成员

来自分类Dev

c ++:初始化成员结构的静态字段的正确方法

来自分类Dev

C ++初始化成员数组

来自分类Dev

c ++构造函数成员初始化:传递参数

Related 相关文章

  1. 1

    如何使用已删除的副本构造函数初始化类数组(C ++ 11)

  2. 2

    使用构造函数初始化数组(C ++)

  3. 3

    为什么就地成员初始化在C ++ 11中使用副本构造函数?

  4. 4

    如何在C ++中使用构造函数初始化2D向量?

  5. 5

    没有初始化列表的初始化成员变量和没有默认构造函数的类型?

  6. 6

    使用默认默认构造函数的C ++ 11值初始化

  7. 7

    C ++:初始化成员向量值

  8. 8

    使用自定义构造函数作为Objective C类成员初始化C ++类的实例吗?

  9. 9

    为什么显式声明的构造函数阻止使用C ++ 11初始化列表进行成员初始化?

  10. 10

    C ++成员初始化和构造函数

  11. 11

    C ++在构造函数初始化列表中获取类成员地址

  12. 12

    如何在C ++中初始化成员的构造函数参数

  13. 13

    用多个构造函数调用初始化成员变量

  14. 14

    C ++构造函数如何初始化其类的对象?

  15. 15

    如何在C ++中使用构造函数(只是构造函数)在类中初始化大型私有数组?

  16. 16

    在使用相同名称的构造函数参数初始化成员变量时,=和{}之间的区别

  17. 17

    C ++:在constexpr构造函数中初始化成员数组

  18. 18

    C ++:具有初始化列表的默认构造函数

  19. 19

    C ++初始化程序列表成员仍在调用默认构造函数?

  20. 20

    在Dart中的可选参数构造函数中使用构造函数初始化成员

  21. 21

    如何根据条件使用不同的构造函数初始化C ++参考?

  22. 22

    如何在C ++中使用构造函数初始化2D向量?

  23. 23

    为什么显式声明的构造函数阻止使用C ++ 11初始化列表进行成员初始化?

  24. 24

    使用已删除的默认构造函数初始化成员

  25. 25

    Matlab-构造函数不会初始化成员值

  26. 26

    如何在Objective-C中使用自定义构造函数初始化自动成员

  27. 27

    c ++:初始化成员结构的静态字段的正确方法

  28. 28

    C ++初始化成员数组

  29. 29

    c ++构造函数成员初始化:传递参数

热门标签

归档