C ++ Несколько классов с одинаковым именем - PullRequest
15 голосов
/ 17 июня 2011

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

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

UPDATE:

Как следует из ответов / комментариев, я искал анонимные пространства имен.

Ответы [ 5 ]

21 голосов
/ 17 июня 2011

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

9 голосов
/ 17 июня 2011

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

См. Пример в 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 в классе родительского списка. Или вы можете добавить свой класс в анонимном пространстве имен. См. Как может тип, который используется только в одном модуле компиляции, нарушать Правило Одного Определения?

6 голосов
/ 17 июня 2011

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

5 голосов
/ 17 июня 2011

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

namespace A {
    class Node { };
}

namespace B {
    class Node { };
}

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

3 голосов
/ 17 июня 2011

Я видел конфликт этих классов.Это ожидается стандартом?

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

...