Страницы

Поиск по вопросам

четверг, 13 февраля 2020 г.

C++. Предварительное объявление членов классов за их пределами

#cpp #классы #объявление


У меня сложилась такая ситуация, что есть два класса, каждый из которых нуждается
в конструкторе другого. Для этого нужно, чтобы они видели не только объявления (прототипы),
но и определения друг друга одновременно, что невозможно. Значит, каждый класс должен
видеть сверху по крайней мере прототип конструктора другого.

Вот мой код:

#include 

class Euros;
Euros::Euros(double euros = 0);

class Dollars
{
    private:
        double m_dollars;

    public:
        Dollars(double dollars = 0) : m_dollars(dollars)
        {
        }

        operator double() const { return m_dollars; }
        operator Euros() const { return Euros(m_dollars * 0.89); }

        double getDollars() const { return m_dollars; }
        void setDollars(double dollars) { m_dollars = dollars; }
};

class Euros
{
    private:
        double m_euros;
    public:
        Euros(double euros) : m_euros(euros)
        {
        }

        operator double() const { return m_euros; }
        operator Dollars() const { return Dollars(m_euros * 1.12); }

        double getEuros() const { return m_euros; }
        void setEuros(double euros) { m_euros = euros; }
};


Здесь для каждого класса перегружается операция преобразования типов друг в друга,
для чего требуется возвращать вновь созданный с помощью конструктора экземпляр противоположного
класса. С классом Euros всё нормально, т.к. он видит полное определение класса Dollars,
а значит видит и конструктор. С классом Dollars всё наоборот: он вообще не видит Euros.
В 3 строке я объявил прототип Euros, но этого недостаточно, т.к. для создания объекта
нужен ещё и конструктор. 

Я знаю, что методы класса достаточно только объявить внутри него, а определение может
быть уже после за его пределами. Но я не знаю, можно ли сделать наоборот: определить
внутри класса, а объявить перед ним. В 4 строке я попытался это сделать, но получил
ошибку "invalid use of incomlete type 'class Euros'". Естественно, были и другие ошибки,
вытекающие из этой, но данная ошибка источник всех проблем.

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


Ответы

Ответ 1



Простое вынесите реализации "перекрёстных" методов (одного из них) наружу из определения класса и поместите ниже - после определения второго класса class Euros; class Dollars { ... operator Euros() const; ... }; class Euros { ... operator Dollars() const { return Dollars(m_euros * 1.12); } ... }; inline Dollars::operator Euros() const { return Euros(m_dollars * 0.89); } Вы и сами написали об этом в вопросе: "Я знаю, что методы класса достаточно только объявить внутри него, а определение может быть уже после за его пределами." Только применять это знание вам надо было обычным способом к вашим операторам преобразования, а не каким-то "вывернутым" образом к конструкторам.

Комментариев нет:

Отправить комментарий