One question about protected constructor. I learnt that the protected constructor can be used in the derived class. How ever, I found the code below has an error. Why does it happen like this?
class A
{
protected:
A(){}
};
class B: public A {
public:
B() {
A* f=new A(); // Why it is not working here
}
};
This has nothing to do with constructors specifically. This is just how
protected
access works.The way
protected
access specifier works, it allows the derived classB
to access the contents of an object of base classA
only when that object of classA
is a subobject of classB
. That means that the only thing you can do in your code is to access the contents ofA
throughB
: you can access the members ofA
through a pointer of typeB *
(or a reference of typeB &
). But you cannot access the same members through a pointer of typeA *
(or referenceA &
).Consider the following example
In the above
B::foo
, you can access base memberA::i
by using just plaini
syntax. This is equivalent to usingthis->i
syntax. Both will work, because the pointerthis
has typeB *
, i.e. you are accessingA::i
thorough a pointer of typeB *
. This is exactly what theprotected
access specifier is supposed to allow. The access throughpb
pointer works for the very same reason.However, when you "convert"
this
pointer to typeA *
, you can no longer accessA::i
through that new pointer, even though you are still trying to access they very same member as before.When applied to constructors, the
protected
access specifier has a very specific effect: a protected constructor can only be used to initialize base-class subobjects. It cannot be used to initialize standalone objects (which is what you were trying to do). In other words, protected constructors are another way to implement the concept of abstract class in C++ (along with pure virtual methods). If the constructors of your class are protected, then your class is effectively abstract. You can't use it to define independent objects "from outside". (Of course, the above does not apply within friends, as well as within the class itself).I had the same question as this, and this link make me clear.
cppreference says like this:
Let me put my answer in steps:
1) Constructors don't get Inherited and that why in derived class, they can't be over ridden.
2) Constructors are invoked and not called.
3) If you have declared a simple function in A say protected void print() and then tried calling it in B, It would have worked. This happens bcoz, B has inherited this function.
4) When you do something like this b : a(), you are invoking the constructor and that's allowed.
5) Try making B a friend class of A and then run and see if it works.
Hope this helps.
When a base class has a protected constructor, you can't instantiate the class directly. But you can do this to call the constructor from the base class constructor:
A direct call to the constructor as shown below gives you the following error with gcc version 4.1.2:
However, you this call to the constructor gives no errors:
The reason behind this is that the second call accesses the A() constructor through inheritance, which is allowed. However, this tries to explicitly create a new instance of A() by calling the constructor directly:
This might seem unintuitive, as B should be able to access A's constructor because B inherits from A. However, if you declare a constructor protected in C++, you can't create an instance of that class except through inheritance or a friend relationship.