Динамический объект не создается для частного класса - PullRequest
0 голосов
/ 06 апреля 2010

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

class base
{
    public:
        void foo()
        { cout << "base::foo()"; }
};

class derived : private base
{
    public:
        void foo()
        { cout << "deived::foo()"; }
};

void main()
{
    base *d = new derived();
    d->foo();
}

Это дает мне ошибку:

"Тип приведения": преобразование из «Производный *» в «базовый *» существует, но недоступный "

Заранее спасибо:)

Ответы [ 6 ]

3 голосов
/ 06 апреля 2010

Проблема в том, что вы используете частное наследование; это означает, что наследование можно увидеть только внутри вашего класса (в данном случае derived). Вы не можете указать base* на derived экземпляр вне вашего класса (в данном случае main()), потому что наследование (и, следовательно, преобразование) не доступно.

Это то же самое, что пытаться получить доступ к закрытому члену вне класса.

На самом деле название «частное наследование» вводит в заблуждение, поскольку оно не реализует настоящее наследование. В вашем примере экземпляр derived не является base; это просто реализовано в терминах base, и это то, что означает «частное наследование». Если у вас возникает соблазн использовать частное наследование, вам следует рассмотреть возможность использования простого агрегирования (то есть частного указателя на base внутри derived). В большинстве случаев (в большинстве случаев, не всегда) частное наследование не дает никаких преимуществ и имеет некоторые тонкие проблемы.

2 голосов
/ 06 апреля 2010

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

 base *d = new derived();

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

derived d;
derived * dp = new derived();
0 голосов
/ 10 января 2011

См. Гл.11.2.3 в стандартах C ++ (черновик). Вы должны использовать явное приведение, потому что конструктор копирования, который использовался в неявном приведении (base * d = new производный ();), недоступен.

0 голосов
/ 06 апреля 2010

Мое предположение: конструктор по умолчанию / конструктор копирования вашего базового класса, созданный вашим компилятором, является закрытым из-за частного наследования вашего производного класса и не может использоваться типом cast

0 голосов
/ 06 апреля 2010

Два способа заставить его работать:

class base
{
    public:
        void foo()
        { std::cout << "base::foo()"; }
};

class derived : public base // <-- make it public
{
    public:
        void foo()
        { std::cout << "derived::foo()"; }
};

void main()
{
    base *d = new derived();
    d->foo();
}

или

class base
{
    public:
        void foo()
        { std::cout << "base::foo()"; }
};

class derived : private base
{
    public:
        void foo()
        { std::cout << "derived::foo()"; }
};

void main()
{
    derived *d = new derived(); // create pointer on derived, not base
    d->foo();
}

Надеюсь, это поможет, Exa

0 голосов
/ 06 апреля 2010

При частном наследовании детали вашего базового класса не видны за пределами производного класса. поэтому ошибка C2243: защита доступа (защищенная или частная) не позволяет преобразовать указатель на производный класс в указатель на базовый класс.

Вместо этого вы должны использовать публичное наследование.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...