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 не инициализирует их?

Я хочу избежать использования новый ключевое слово (которое решило бы всю проблему).

РЕДАКТИРОВАТЬ:
Кажется, что людям трудно понять вопрос и дилемму. Я постараюсь объяснить:

Я хочу принудительно использовать конструктор Foo (BAZ), что означает, что любая попытка использовать конструктор Foo (void) приведет к ошибке.

Чтобы скрыть конструктор по умолчанию, он объявлен как закрытый член. Если кто-то попытается использовать конструктор по умолчанию Foo (), это даст преднамеренную ошибку.

Не объявлять конструктор по умолчанию и только объявлять Foo (BAZ) не мешает компилятору создавать общедоступный конструктор по умолчанию. Это не дает ошибки, если я объявляю это Foo (). Пока что работает нормально и как задумано.

Второй класс Bar имеет два экземпляра Foo, но при создании экземпляра Bar эти члены Foo будут вызываться с помощью конструктора по умолчанию (скрытый) и генерировать ошибку. Затем в конструкторе Bar эти два экземпляра будут инициализированы с помощью правильного открытого конструктора Bar (BAZ a, BAZ b): foo1 (a), foo2 (b). Это то, что я хочу.

Есть ли способ предотвратить вызов конструктором Foo по умолчанию при инициализации Bar, чтобы конструктор Bar мог использовать правильный конструктор Foo?

новый Решение работает, потому что конструктор по умолчанию никогда не вызывается:

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

Я надеюсь, что это делает это более ясным.

EDIT2: решено
Ошибка не в скрытом конструкторе Foo, а в скрытом конструкторе Bar, пытающемся использовать скрытые конструкторы Foo по умолчанию.

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

Решил это.

EDIT3:
Реальная проблема, кажется, была в инструменте разработки. После перезапуска и очистки кэша вручную он работал в соответствии со стандартом C ++ 14.

-4

Решение

объявление переменных foo1 и foo2 вызовет значение по умолчанию
Конструктор Foo

Нет. Объявление этих переменных-членов только говорит, что они являются членами. Это ничего не говорит о том, как они будут построены. Это работа конструктора (ов) класса, который их использует.

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

Хорошо до сих пор: этот конструктор создает foo1 а также foo2 члены, использующие конструктор Foo(Baz),

Bar(void) {}

Это проблема: он пытается построить foo1 а также foo2 члены с конструктором по умолчанию для Foo, Поскольку этот конструктор не доступной (это правильный термин; это не скрытый), вы получаете ошибку. Есть как минимум три решения:

1:

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

Это использует конструктор, который принимает Baz,

2:

Bar() = delete;

Это делает конструктор по умолчанию для Bar не существует, поэтому он не пытается использовать конструктор по умолчанию для Foo,

3:

Просто не делай этого. Если вы не пишете конструктор по умолчанию, но пишете другой, компилятор не будет генерировать конструктор по умолчанию.

6

Другие решения

Не скрывайте конструкторов. Не объявляйте их в первую очередь.

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) { ... }
};
5

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector