Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Как предварительно описать струкутру


Автор: nns2009 3.10.2011, 18:19
Сейчас пишу геометрию, и мне нужно чтобы структура Line имела доступ к Vector и наоборот.
Код

struct Line;
struct Vector;

struct Line
{
    ...
    Line(Vector& from, Vector& to)
    {
        a = from.y - to.y; // Это выделенная строчка
        b = to.x - from.x;
        c = -(a * from.x + b * from.y);
    }
};

struct Vector
{
    ...
    bool onLine(Line& l)
    {
        ...
    }
};


Пробовал написать так, как показал (предварительно объявить структуры (struct Line; struct Vector;) ), но в ответ мне выдаётся ошибка начиная с выделенной строчки. Где я ошибся и что надо исправить?

Автор: boostcoder 3.10.2011, 18:31
Цитата(nns2009 @  3.10.2011,  18:19 Найти цитируемый пост)
Line имела доступ к Vector и наоборот

самое время обобщить схожие моменты и вынести их в общий базовый тип.

Добавлено через 1 минуту и 20 секунд
Цитата(nns2009 @  3.10.2011,  18:19 Найти цитируемый пост)
в ответ мне выдаётся ошибка начиная с выделенной строчки

потому что использовать Vector можно после описания реализации, а не форварда.

Автор: nns2009 3.10.2011, 18:37
Цитата(boostcoder @  3.10.2011,  18:31 Найти цитируемый пост)
потому что использовать Vector можно после описания реализации, а не форварда. 

А как поступить мне, не могли бы вы привести код: я долгое время программировал на C#, где об этом можно не задумываться и теперь немного непревычно...

Автор: boostcoder 3.10.2011, 18:39
Цитата(nns2009 @  3.10.2011,  18:37 Найти цитируемый пост)
А как поступить мне

-
Цитата(boostcoder @  3.10.2011,  18:31 Найти цитируемый пост)
обобщить схожие моменты и вынести их в общий базовый тип.


Добавлено через 1 минуту и 1 секунду
взаимная зависимость - это не хорошо.

Автор: newbee 3.10.2011, 19:18
Выноси объявления структур в .h-файл(ы), а реализацию методов - в .cpp.

Цитата(boostcoder @  3.10.2011,  19:31 Найти цитируемый пост)
самое время обобщить схожие моменты и вынести их в общий базовый тип.
ООП головного мозга.

Добавлено через 1 минуту и 52 секунды
Собственно в разные файлы выносить даже не обязательно. Суть: сначала в исходнике должны быть полностью объявлены обе структуры, а ниже может быть реализован код методов.

Автор: mes 3.10.2011, 19:27
вынести реализацию в .cpp ,  куда и включать нужные хидеры..
в остальных местах использовать forward declaration..

Добавлено через 3 минуты и 27 секунд
Цитата(boostcoder @  3.10.2011,  17:31 Найти цитируемый пост)
самое время обобщить схожие моменты и вынести их в общий базовый тип.

в данном вопросе это не лучшее решение.. smile

Добавлено через 4 минуты и 37 секунд
newbee, а ньюби оказывается  уже все написала..

Добавлено через 7 минут и 1 секунду
Цитата(mes @  3.10.2011,  18:27 Найти цитируемый пост)
в данном вопросе это не лучшее решение.

т.е. нужно не искать базовый класс, а наоборот, выделить еще один (после-) слой, в который и вынести операции по взаимной геометрии.. 

Автор: math64 4.10.2011, 17:12
gcc такое компирирует:
Код
class A {public:
  class B;
  class C;
  void f(B b, C c) { b=b; c=c; }
  class B {
  public:
    void f(C c) { c=c; }
  };
  class C {
  public:
    void f(B b) { b=b; }
  };
};
int main()
{
A a;
A::B b;
A::C c;
a.f(b,c);
b.f(c);
c.f(b);}

Т.е. для вложенного класса без полей достаточно только предварительного объявления, чтобы его копировать.
(не проверял, как ведут другие компиляторы)
Но если добавить поля, уже не компилируется:
Код
class A {
public:
  class B;
  class C;
  void f(B b, C c) { b.a=c.a; }
  class B {
  public:
    void f(C c) { a=c.a; }
    A a;
  };
  class C {
  public:
    void f(B b) { a=b.a; }
    A a;
  };
  int x;
};
int main()
{
A a;
A::B b;
A::C c;
a.f(b,c);
b.f(c);
c.f(b);
}


Добавлено @ 17:20
Так тоже компилируется:
Код
class A {
public:
  class B;
  class C;
  void f(B b, C c) { b.a=c.a; }
  class B {
  public:
    void f(C c) { a=c.a; c.f(*this); }
    int a;
  };
  class C {
  public:
    void f(B b) { a=b.a; }
    int a;
  };
};
int main()
{
A a;
A::B b;
A::C c;
a.f(b,c);
b.f(c);
c.f(b);
}

т.е. нужно чтобы вложенные классы не обращались к внешнему

Автор: xvr 5.10.2011, 13:45
Цитата(math64 @  4.10.2011,  17:12 Найти цитируемый пост)
Т.е. для вложенного класса без полей достаточно только предварительного объявления, чтобы его копировать.
(не проверял, как ведут другие компиляторы)

Должны так же. В С++ (по стандарту) тела функций-членов компилируются в контексте полного описания класса, к которому они принадлежат. Т.е. включая и то, что определено в классе после них.

Автор: newbee 5.10.2011, 13:55
Мда, в этом все С++-сники. Половина работы - борьба с языком.

Автор: math64 5.10.2011, 14:23
Цитата(xvr @  5.10.2011,  13:45 Найти цитируемый пост)
Должны так же. В С++ (по стандарту) тела функций-членов компилируются в контексте полного описания класса, к которому они принадлежат. Т.е. включая и то, что определено в классе после них.

Всё таки не понятно тогда, почему мой второй пример не компилируется - т.е. функции-члены вложенного класса компилируются в контексте когда уже имеются полные описания вложенных классов, но для внешнего класса ещё полного описания нет.

T.о. если топик-стартер хочет программировать в стиле C#, он может поместить свои классы во внешний класс:
Код

struct graphics {
class Vector;
class Line;
class Vector { };
class Line { };
};
typedef graphics::Vector Vector;
typedef graphics::Line Line;


Автор: xvr 5.10.2011, 17:41
Цитата(math64 @  5.10.2011,  14:23 Найти цитируемый пост)
Всё таки не понятно тогда, почему мой второй пример не компилируется - т.е. функции-члены вложенного класса компилируются в контексте когда уже имеются полные описания вложенных классов, но для внешнего класса ещё полного описания нет.
Поэтому и не компилируются, т.к. обращаются к полям внешнего класса, а он еще не до конца описан. А правило, по которому компиляция функций-членов откладывается до конца описания класса, не распространяется на вложенные классы

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)