Вызов конструктора базового класса вручную вне списка инициализации - PullRequest
0 голосов
/ 17 июня 2020

У меня есть класс Derived, конструктор которого должен заполнять поля класса struct, который передается в качестве аргумента конструктору класса Base. Я хочу иметь возможность называть поля структуры, которую я заполняю, чтобы мой код соответствовал требованиям будущего (то есть: устойчив к добавлению и / или изменению порядка членов MyStruct).

Примечание этот struct MyStruct имеет значения по умолчанию, поэтому он не может быть инициализирован именованными полями непосредственно в списке инициализации (например: Base({.a = a, .b = b}) не работает). Кроме того, в моем случае удален конструктор копирования Base. Кроме того, я использую C ++ 11.

В решении, которое я придумал, используется оператор placement new для ручного вызова конструктора класса Base в памяти, на которую указывает this. Для этого мне также пришлось добавить конструктор по умолчанию protected в мой класс Base. Есть ли у этого подхода какие-либо возможные недостатки и / или кто-нибудь может предложить лучший метод?

Ответы [ 2 ]

2 голосов
/ 17 июня 2020

Используйте вспомогательную функцию вместо

class Derived : public Base
{
public:
        Derived(int a, int b) : Base(make_mystruct(a, b)), anothermember(some_value) {}
private:
        int anothermember;
        static MyStruct make_mystruct(int a, int b) { return MyStruct(a, b); }
};
1 голос
/ 19 июня 2020

Я просто хотел бы добавить, что это может быть хорошей возможностью использовать IILE , немедленно вызываемое лямбда-выражение, если вам по какой-либо причине не нужна именованная вспомогательная функция:

class Derived : public Base
{
public:
Derived(int a, int b) : Base{[](){
    MyStruct str;
    str.a = a;
    str.b = b;
    return str; }()}
    {}
};

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...