Как обрабатывать объекты, которые не имеют конструктора по умолчанию, но построены в другом конструкторе? - PullRequest
1 голос
/ 21 января 2020

У меня есть следующий пример кода

class ClassB {
    public:
    ClassB(int i); // No default constructor
}

class ClassA {
    ClassB obj; //NOT a pointer
    public 
    ClassA() {
        //calculate someInt;
        obj = ClassB(someInt); // doesnt work
    }

}

Как мне инициализировать obj? Компилятор жалуется на no appropriate default constructor available для obj

Ответы [ 2 ]

2 голосов
/ 21 января 2020

Лучшим решением для вас было бы инициализировать элемент obj в списке инициализации следующим образом:

ClassA() : obj(someInt) { }

Однако другой вариант для вас - объявить конструктор по умолчанию для ClassB, например:

ClassB() {}

или просто позволить компилятору создать его для вас, используя это:

ClassB() = default;

Из C ++ Standard это:

конструктор по умолчанию по умолчанию: компилятор определит неявный конструктор по умолчанию, даже если присутствуют другие конструкторы.

Если вы go для второй опции, тогда следующий код пройдет без ошибки:

#include <iostream>

class ClassB {
public:
    ClassB() = default;
    ClassB(int i);
};

class ClassA {
    ClassB obj;
public: 
    ClassA() {
        int someInt = 0;
        obj = ClassB(someInt);
    }
};

int main() {

    return 0;
}

Проверьте это Live

Вывод

Я бы настоятельно рекомендовал использовать первый вариант один со списком инициализации, потому что нет необходимости предварительно создавать объекты по умолчанию и затем назначать их. Кроме того, это единственная опция для объектов, у которых нет оператора присваивания.

ОБНОВЛЕНИЕ 1

Еще один способ решения этой проблемы - использовать std::shared_ptr<ClassB> obj в вашем ClassA следующим образом:

#include <iostream>
#include <memory>

class ClassB {
public:
    ClassB(int i);
};

class ClassA {
    std::shared_ptr<ClassB> obj;
public: 
    ClassA() {
        int someInt = 0;
        obj = std::make_shared<ClassB>(someInt);
    }
};

int main() {

    return 0;
}

ОБНОВЛЕНИЕ 2

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

#include <iostream>

class ClassB {
public:
    ClassB(int i);
};

class ClassA {
    ClassB obj;
public: 
    ClassA()
        : obj(calculate())
    {}

private:
    int calculate() {
        return 1;
    }
};

int main() {
    return 0;
}

Проверить вживую

1 голос
/ 21 января 2020

Вы инициализируете элементы в списке инициализации конструктора. Вот так:

ClassA() : obj(someInt) { }
...