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

Частное наследование скрывает базовый класс с ошибкой "недопустимый в этом контексте"

У меня проблема, подобная той, что описана в следующей ссылке, где частный унаследованный базовый класс дает ошибку "недоступность в этом контексте", когда я пытаюсь объявить член базового класса внутри производного класса: http://bytes.com/topic/c/answers/164246-private-inheritance-renders-class-inaccessible

Явное указание X с:: X работает в приведенном выше случае, но что, если код находится в такой функции, как:

void fooby()
{
    class X {};

    class Y : private X {};

    class Z : public Y
    {
    public:
        X x; // compiler "inaccessible within this context" error
    };
};

Как вы ссылаетесь на X в этом случае?

Если fooby был struct/class, тогда:: fooby:: X будет работать, но я не уверен, как это сделать в приведенном выше случае.

4b9b3361

Ответ 1

Проблема, с которой вы сталкиваетесь, заключается в том, что в Y (и всех производных типах) есть указатель X, который ссылается на X, который недоступен ниже Y.

В общем случае определяемых пользователем типов, объявленных на уровне пространства имен, вы можете использовать пространство имен для определения типа и получения доступа:

class X {};
class Y : X {};
class Z : Y {
   ::X x;            // or Namespace::X
};

Потому что вы определяете свои типы внутри функции, которая не является допустимой.

В качестве альтернативы вы можете обойти проблему с другими обходными решениями. Как предложил @Eugene, вы можете создать альтернативный идентификатор для ссылки на X:

typedef class X {} another_name;
class Y : X {};
class Z : Y { 
   another_name x;
};

Или вы можете добавить typedef внутри Y, чтобы предоставить тип производным типам:

class X {};
class Y : X {
public:
   typedef X X;
};
class Z : Y {
   X x;
};

Этот последний параметр работает, потому что он добавит идентификатор X внутри Y, который public, и относится к типу, поэтому компилятор найдет там тип и использует его в Z.

Ответ 2

Хороший вопрос, я не могу найти способ сделать это. Единственный вариант, который я вижу, - ввести typedef вне Z:

typedef X PITA;
class Z : public Y
{
public:
    PITA x; // ok
};