Проблема с внутренними классами с таким же именем в Visual C ++ - PullRequest
4 голосов
/ 07 мая 2010

У меня проблема с Visual C ++ 2005, где, по-видимому, перепутаны внутренние классы с одинаковыми именами, но в разных внешних классах.

Проблема возникает для двух уровней, где каждый уровень имеет интерфейс слушателя в качестве внутреннего класса. B является слушателем A и имеет собственный слушатель в третьем слое над ним (не показан).

Структура кода выглядит следующим образом:

хиджры

class A
{
public:
    class Listener
    {
    public:
        Listener();
        virtual ~Listener() = 0;
    };
    // ...
};

B.h

class B : public A::Listener
{
    class Listener
    {
    public:
        Listener();
        virtual ~Listener() = 0;
    };
    // ...
};

A :: Listener () и A :: ~ Listener () определены в A.cpp.

B.cpp

B::Listener::Listener() {}
B::Listener::~Listener() {}

Я получаю ошибку

B.cpp(49) : error C2509: '{ctor}' : member function not declared in 'B'

Компилятор C ++ для Renesas sh2a не имеет проблем с этим, но в некоторых других отношениях он более либерален, чем Visual C ++.

Если я переименую интерфейсы слушателя, чтобы они имели разные имена, проблема исчезнет, ​​но я бы хотел этого избежать (реальные имена классов вместо A или B довольно длинные).

Правильно ли я делаю C ++ или жалоба Visual C ++ оправдана?

Есть ли способ обойти эту проблему без переименования интерфейсов слушателя?

1 Ответ

1 голос
/ 07 мая 2010

код, который вы разместили, выдает ту же ошибку компилятора, которую вы описали на моей машине. Я сам не совсем уверен, в чем именно заключается проблема, но у меня есть ощущение, что наследование от чистого виртуального класса и объявление чистого виртуального класса в потомке может быть плохой идеей.

Мне удалось скомпилировать модифицированную версию, возможно, это поможет вам решить ваши проблемы:

class OuterA
{
  public:
    class Listener
    {
      public:
        Listener() {}
        virtual ~Listener() = 0 {}
    };

    OuterA() {}
    ~OuterA(){}
};

class OuterB : public OuterA::Listener
{
  public:
    class Listener
    {
      public:
        Listener()  {}
        ~Listener() {}
    };

    OuterB()  {}
    ~OuterB() {}
};

// РЕДАКТИРОВАТЬ, чтобы избежать встроенного ctor и dtor

Если вы используете typedefs, чтобы скрыть имена слушателей, по крайней мере, мой демонстрационный код компилирует и ссылки:

// header

class OuterA
{
  public:
    class Listener
    {
      public:
        Listener();
        virtual ~Listener() = 0;
    };

    OuterA();
    ~OuterA();
};   

class OuterB : public OuterA::Listener
{
  public:
    class Listener
    {
      public:
        Listener();
        virtual ~Listener() = 0;
    };

    OuterB();
    ~OuterB();
};

// реализация

OuterA::OuterA(){}
OuterA::~OuterA(){}

OuterA::Listener::Listener(){}
OuterA::Listener::~Listener(){}

typedef OuterB::Listener BListener;

OuterB::OuterB() {}
OuterB::~OuterB(){}

BListener::Listener(){}
BListener::~Listener(){}
...