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

С++ Несколько классов с одинаковым именем

Скажем, у меня есть два разных файла cpp. Оба объявляют классы с одинаковым именем, но, возможно, совершенно другую структуру (или, возможно, одну и ту же структуру, другую реализацию). Классы не отображаются в файлах заголовков. (В качестве примера предположим, что они являются классами Node для разных классов списка.)

Я видел конфликты этих классов. Ожидается ли это по стандарту? Какие решения существуют для этой проблемы?

4b9b3361

Ответ 1

Стандартный способ решения этой проблемы - обернуть классы в разные namespaces.

Ответ 2

Вы можете использовать пространство имен для того, чтобы иметь несколько классов с одинаковым именем, путем подбора их в разных пространствах имен. См.: http://www.cplusplus.com/doc/tutorial/namespaces/

Ответ 3

Он нарушает Одно правило определения. Это сложно для компилятора обнаружить ошибку, потому что они находятся в разных единицах компиляции. И даже компоновщик не может обнаружить все ошибки.

См. пример в http://www.cplusplus.com/forum/general/32010/. Мой компилятор и компоновщик (g++ 4.2.1) могут создавать окончательный исполняемый файл без каких-либо ошибок, но вывод неверен.

Если я немного изменил пример, у меня возникла ошибка сегментации.

// main.cpp
#include <iostream>
#include <list>
using namespace std;

struct Handler
{
    Handler() : d(10, 1.234) {}
    list<double> d;
};

extern void test_func();

int main(void)
{
    Handler h;
    cout << h.d.back() << endl;
    test_func();
    return 0;
}
// test.cpp
#include <iostream>
#include <string>
using namespace std;

struct Handler
{
    Handler() : d("test Handler")  {}
    string d;
};

void test_func()
{
    Handler h;
    cout << h.d << endl;
}

Рекомендуется разграничить класс по пространству имен. Например, Node, вы можете использовать класс nest и определить Node в классе родительского списка. Или вы можете добавить класс в анонимное пространство имен. См. Как тип, который используется только в одном модуле компиляции, нарушает правило одного определения?

Ответ 4

Я не уверен, что здесь не хватает некоторых деталей, но вы переносите каждый класс в namespace.

namespace A {
    class Node { };
}

namespace B {
    class Node { };
}

Затем вы можете использовать A::Node или B::Node.

Ответ 5

Я видел конфликты этих классов. Ожидается ли это по стандарту?

В стандарте говорится, что вы не можете этого сделать. Это будет нарушать одно правило определения. (Как исправить это уже было рассмотрено в других ответах)