Предварительно объявление структуры

210
03 апреля 2019, 13:20

Есть две структуры, реализующие геометрические понятия точки и вектора. Для инициализации вектора требуется две точки. Аналогично присутствует операция сложения точки и вектора через перегрузку оператора +. Компилятор ругается на отсутствие структуры Vector в перегрузке, что понятно, т.к. она реализована после. Каким образом предварительно объявить структуру Vector. (struct Vector;) не работает. Или тут ошибка самой логики объявления.

struct Vector;
struct Point
{
    int X;
    int Y;
    [***] 
    Point operator + (const Vector& ab)
    {
        this->X += ab.X;
        this->Y += ab.Y;
        return *this;
    }
};

struct Vector
{
    int X;
    int Y;
    [***]
    Vector(Point& a, Point& b)
    {
        X = b.X - a.X;
        Y = b.Y - a.Y;
    }
};
Answer 1

С логикой предварительного объявления все в порядке. Просто определение вашего оператора надо делать там, где определения обоих классов уже полностью известны. Т.е. не внутри первого класса, а снаружи - после обоих определений классов, как inline

inline Point Point::operator + (const Vector& ab)
{
    this->X += ab.X;
    this->Y += ab.Y;
    return *this;
}

Внутри первого класса должно остаться только объявление оператора.

Однако реализовано у вас тут нечто странное. Бинарный оператор +, который вдруг ни с того ни с сего портит (модифицирует) свой первый операнд - это ужасно. Зачем вам понадобился такой странный оператор?

Answer 2

Вынесите определение оператора вне класса, после объявлений обоих классов. В классе оставьте только объявление оператора, без тела. Примерно так:

struct Vector;
struct Point
{
    int X;
    int Y;
    [***] 
    Point operator + (const Vector& ab);
};

struct Vector
{
    int X;
    int Y;
    [***]
    Vector(Point& a, Point& b)
    {
        X = b.X - a.X;
        Y = b.Y - a.Y;
    }
};
Point Point::operator + (const Vector& ab);
{
    X += ab.X;
    Y += ab.Y;
    return *this;
}
Answer 3

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

class my_class;

перед классом, в котором будете размещать указатель на my_class.

UPD говоря класс - я имел ввиду понятие в общем, а не конкретно class

READ ALSO
Можно ли сравнивать float с нулем?

Можно ли сравнивать float с нулем?

Все мы знаем, что к float нельзя (точнее не рекомендуется) применять операцию ==Почему - думаю сами знаете

141
OpenProcess не возвращает хэндл процесса

OpenProcess не возвращает хэндл процесса

OpenProcess не возвращает хэндл процесса, при этом hwnd и procID не равен NULL

143
Задача “Игра” C++

Задача “Игра” C++

Условие задачи на картинкеКод что я написал ниже: Почему-то всегда если ввожу большое число(около 1 * 10^10) выдает результат 17:174

130
С3863: Тип массива char[64] является неоднозначным

С3863: Тип массива char[64] является неоднозначным

Примитивная программа, при компилировании которой выходит две ошибки:

135