views:

48

answers:

5

Hi,

What is the reason for the following code that does not let me to create object.

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();
}

It Gives me error :

" 'type cast' : conversion from 'derived *' to 'base *' exists, but is inaccessible"

Thanks in advance :)

+2  A: 

The problem is that you are using private inheritance; this means that inheritance can only be seen inside your class (in this case, derived). You cannot point a base* to a derived instance outside your class (in this case, in main()) because the inheritance (and hence, the conversion) cannot be accessed.

This is exactly the same as trying to access a private member from outside a class.

In fact, the name "private inheritance" is quite misleading, since it does not implement real inheritance. In your example, a derived instance is not a base; it is just implemented in terms of a base, and this is what "private inheritance" means. If you are tempted to use private inheritance, you should consider the possibility of using simple aggregation (i.e.: a private pointer to base inside derived) instead. In most cases (most cases, not always), private inheritance offers no advantages and has some subtle problems.

Gorpik
+1 and to re-iterate: "it [derived] is just implemented in terms of a base, and this is what "private inheritance" means"
digitalarbeiter
Nice Answer Gorpik :).
mahesh
Glad that it was of use.
Gorpik
A: 

Private inheritance causes your base class details to not to visible outside of derived class. so the error C2243: Access protection (protected or private) prevented conversion from a pointer to a derived class to a pointer to the base class.

You should use public inheritance instead.

aJ
A: 

Two ways to make it work:

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();
}

or:

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();
}

Hope that helps, Exa

Exa
Also you probably want to make foo() virtual
digitalarbeiter
A: 

My guess: the default constructor/copy constructor of your base class created by your compiler is private due to private inheritance to your derived class and can't by used by the type cast

DaClown
That's nonsense. We're talking private inheritance here.
sbi
+2  A: 

Because you used private inheritance, a derived object is not a kind of base object. So when you say:

 base *d = new derived();

the pointer to a derived cannot be converted to a pointer to a base - there is no real relationship between the two. You can create derived objects though:

derived d;
derived * dp = new derived();
anon