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

C++ How to initialize members with hidden default constructors?

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

的两个实例
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) 不会阻止编译器创建 public 默认构造函数。如果我将它声明为 Foo(),它不会出错。到目前为止它工作正常并且符合预期。

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

有什么办法可以避免在Bar初始化时调用Foo的默认构造函数,让Bar构造函数使用正确的Foo构造函数吗?

new 解决方案有效,因为从不调用默认构造函数:

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

我希望这能让它更清楚。

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

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

解决了。

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

不要隐藏构造函数。不要首先声明它们。

typedef struct { ... } BAZ;

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

class Bar {
  private:
    Foo foo1;
    Foo foo2;

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

the declaration of the variables foo1 and foo2 will call the default Foo constructor

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

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

到目前为止一切正常:此构造函数使用构造函数 Foo(Baz).

构造 foo1foo2 成员
Bar(void) {}

这就是问题所在:它试图用 Foo 的默认构造函数构造 foo1foo2 成员。由于该构造函数不是 accessible(这是正确的术语;它不是 hidden),您会得到一个错误。至少有三种解决方案:

1:

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

这使用采用 Baz 的构造函数。

2:

Bar() = delete;

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

3:

只是不要这样做。如果您不编写默认构造函数而编写另一个默认构造函数,编译器将不会生成默认构造函数。