Подтвердить что ты не робот

Форвардная декларация и пространства имен (С++)

Моя проблема:

Получили два класса, класс A и B, поэтому я получил A.h и A.cpp и B.h и B.cpp. Необходимо знать, что B и B должны знать A. Я решил это следующим образом (я не знаю, почему это должно быть так...)

хиджры:

#include "B.h"
class A{ ... 

a.cpp:

#include "A.h"

B.h:

#include "A.h"
class A; // forward declaration
class B { ... 

B.cpp:

#include "B.h"

Я использовал одно прямое объявление, и оно работает.

Проблема заключается в том, что оба класса должны находиться в пространстве имен "ui". Или, по крайней мере, я думаю, что это значение:

хиджры:

#include "B.h"
namespace ui{
  class A;
}

class A{ ... 

B.h:

#include "A.h"
namespace ui{
  class B;
}

class B{ ... 

Это больше не работает. Что мне теперь нужно сделать, чтобы он снова работал с пространством имен и декларацией?

Оба должны находиться в этом пространстве имен. Я работаю с Qt, и нужны строки "namespace ui" и т.д. И оба класса должны знать друг друга. Я уже пробовал просто сделать это:

namespace ui{
 class A;
 class B;
}

в обоих заголовках, но это не работает...

Btw: Все заголовки также получили "ifndef" -механизм.

4b9b3361

Ответ 1

Если вы правильно поняли, вы объявляете 2 разных типа с такой конструкцией:

#include "B.h"
namespace ui{
  class A;
}

class A{ ... }; 

Здесь вы указываете, что существует class A в пространстве имен ui, но вы определяете class A в глобальном пространстве имен. Поэтому ui::A объявляется, но никогда не определяется. Переместите определение A в пространство имен ui:

#include "B.h"
namespace ui{
  class A;
}

//somewhere later:
namespace ui
{
  class A{ ... };
}

Ответ 2

// A.h
namespace ui {
   class A; // forward
   class B {
   };
}



// B.h
namespace ui {
   class B; // forward
   class A {
   };
}



// A.cpp
#include "A.h"
#include "B.h"



// B.cpp
#include "A.h"
#include "B.h"

Ответ 3

Ты почти там. Это должно работать:

// A.h
namespace ui {

class B;
class A {
  ...
};

} // namespace ui

и

// B.h
namespace ui {

class A;
class B {
  ...
};

} // namespace ui

Единственное, что вы ошиблись, это то, что вам нужно определить классы внутри пространства имен; его недостаточно, чтобы переслать - объявить их внутри пространства имен.

Ответ 4

Это очень специфичный Qt вопрос.

Когда Qt Designer автоматически создает файл кода для вас, пространство имен Ui является отдельным пространством имен из ваших классов. На самом деле здесь объявляются два разных класса: class A в глобальном пространстве имен и class Ui::A в пространстве имен Ui. Второй класс содержит все элементы управления, которые Qt генерирует для вас (когда вы используете конструктор форм), а первый класс (в глобальном пространстве имен) имеет всю вашу логику.

Версия Qt Creator, которую я использую (3.1), также будет генерировать частный член для class A (not Ui::A): private: Ui::A* ui;, который устанавливается с помощью ui->setUp(this). Затем вы можете получить доступ к элементам управления (например, ui->lineEdit->toPlainText();.