Tom
Tom

Reputation: 9643

c++ can't instantiate a subclass due to parent protected constructor?

This is the code i have trouble understanding:

class A 
{ 
protected: 
   int _i; 
   A () : _i(0) { } 
   ~A () { } 
}; 

class B: public A 
{ 
public: 
   A *_pa; 
   B()  : A(), _pa(new A())
   { } 

  ~B () 
   { 
      delete _pa; 
   } 
}; 

int main () 
{ 
   A a; //ERROR
   B b; //ERROR
}

When trying to instantiate a class of type A i get an error because it's constructor is protected. But why can't I instantiate a class of type B? The class has access to protected members of A (including the ctor) so it should compile.

Upvotes: 3

Views: 611

Answers (4)

Fredrick Gauss
Fredrick Gauss

Reputation: 5166

At the constructor of B, A constructor is called. Because of A's constructor is protected, calling A's constructor at the B's constructor gives error. Also in the protected scope of A, there is destructor. When B's destructor is invoked, its base class (A)'s destructor is called also. Because A's destructor is protected, there occurs another error also. If you take the out the A's constructor off from the B's constructor, there still shows error. But you can get rid of the errors after making public the A's destructor.

public:
   ~A () { }

This deduction made by inspection the errors given by codeblocks, but seems wrong. Removing _pa(new A()) is the exact solution.@AndréPuel 's answer more correct.

Upvotes: -1

pelletjl
pelletjl

Reputation: 505

Deriving from A only gives you access to protected members that you access through "this" or through another B. B doesn't have access to _pa's protected members.

Upvotes: 4

Ivaylo Strandjev
Ivaylo Strandjev

Reputation: 70929

You have an error in main. In there you can not instantiate A, because its constructor is protected.

Additionally you are not able to call the constructor of _pa in the constructor of B.

Upvotes: 0

André Puel
André Puel

Reputation: 9179

Your error is located the new A inside the B constructor, not on the call to super's constructor.

Let me explain you how protected works. When you have a class B, which is subclass of A it does not have access to protected elements of A, it has access to protected elements of A when dealing with a B reference.

To show my point:

#include <iostream>

class A {
protected:
    int a;
};

class B : public A {
public:
    void do_it(A* a) {
        std::cout << a->a << std::endl; //ERROR
    }
    void do_it(B* a) {
        std::cout << a->a << std::endl; //VALID CODE
    }
};

I guess the reason behind this behavior is that if you have a third class C which also access A protected members, probably it is not a good idea that someone else change these protected values.

Upvotes: 4

Related Questions