Использование объекта класса в другом классе до его определения

165
13 октября 2021, 17:00

Есть пример который компилируется

class B;
class A
{
public:
    A(){};
    ~A(){};
private:
    B* m_b;
};
class B
{
    public:
    B(){};
    ~B(){};
};

Но мне нужен вариант, когда в классе А объявлен не указатель на класс B, а его объект. Однако такой код не компилируется. Подскажите как быть, не меняя при этом порядок определения классов?

class B;
class A
{
public:
    A(){};
    ~A(){};
private:
    B m_b;
};
class B
{
    public:
    B(){};
    ~B(){};
};
Answer 1

Без объявления сущности, вы не можете говорить о нем каким то образом. Если речь идет об определении, как в вашем примере(вы объявили, а потом определили), то...

Вы не смоете создать обьект еще неопределенного типа, так же, как вы не сможете иметь то, чего не существует во вселенной. Если ваши классы ничего не делают, то компилятор сам сгенерирует конструктор и деструктор с пустым телом, так что нет необходимости их написать. Также нет смысла объявлять класс, который вы будете определять как пустой. Сразу можете так и определять:

class B{}; //теперь класс определен
class A
{        
    B m_b; 
};

Если же ваши классы не такие простые, а суть в том, чтобы в классе А иметь возможность работать с конкретным обьектом, то в нем вы можете хранить ссыльку на этот класс, точно также, как и вы можете представить что будете иметь то, что еще не существует во вселенной, а потом создать это. Значит, в таком случаи класс А должен получать этот обьект, чтобы инициализировать свою ссыльку. Я приведу простой пример:

class B;
class A {
    const B& m_b; //может быть и неконстантная
    //...
public:
    A(const B& b) : m_b(b) {}
    //...
};
//вывод целочисленного аргумента
class B {
protected:
    const int n;
public:
    B(const int k) : n(k) { std::cout  << n << '\n'; }
};
//а вдруг нам нужно другое определение, например    
//вывод количества цифр целочисленного аргумента
struct B2 : public B {
public:
    B2(int k) :B(std::ceil(log10(k))) {}
};

Вы можете добавить любое определение любого класса, являющимся наследником В (можете подумать о любой вещи и потом создать), и создать экземпляры А с ссыльками на них, таким образом работая с конкретным обьектом. (Правда, что хранить в классе ссыльки _ дело тонькое, и это уже отдельный вопрос). Пример программы:

A a(B(123)), //вывод числа
    a2( B2(123)); //вывод количества цифр
READ ALSO
c++ push_back правильно ли написал?

c++ push_back правильно ли написал?

у меня все работает хорошо, но в arr[0] где то присваивается 0Поэтому я пишу в PrintArray int i = 1

244
перегрузка operator+ c++

перегрузка operator+ c++

я написал перегрузку оператора+ для класса Dinamic:

185
Управление SVG подключенного через img

Управление SVG подключенного через img

Можно ли, с помощью JS, как-то управлять стилями, атрибутами svg, который подключен через тег img ?

115