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 } };
Protecting a constructor prevents the users from creating the instance of the class, outside the package. During overriding, when a variable or method is protected, it can be overridden to other subclass using either a public or protected modifier only. Outer class and interface cannot be protected.
Modifiers public, protected and, private are allowed with constructors. We can use a private constructor in a Java while creating a singleton class.
Typically, constructors have public accessibility so that code outside the class definition or inheritance hierarchy can create objects of the class. But you can also declare a constructor as protected or private . Constructors may be declared as inline , explicit , friend , or constexpr .
The only way to cause a protected constructor to be called is to derive from the class and have the derived class delegate to it or to have a static method create it or some other internal method.
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:
class A { protected: A() {} }; class B: public A { public: B() : A() // allowed to access constructor like this { A* f = new A(); // Not allowed to access constructor like this! } };
A direct call to the constructor as shown below gives you the following error with gcc version 4.1.2:
A* f = new A(); // Not allowed to access constructor like this! test.cpp:4: error: A::A() is protected
However, you this call to the constructor gives no errors:
B() : A() // allowed to access constructor like this
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:
A* f = new A(); // Not allowed to access constructor like this!
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.
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 class B
to access the contents of an object of base class A
only when that object of class A
is a subobject of class B
. That means that the only thing you can do in your code is to access the contents of A
through B
: you can access the members of A
through a pointer of type B *
(or a reference of type B &
). But you cannot access the same members through a pointer of type A *
(or reference A &
).
Consider the following example
class A { protected: int i; }; class B : A { void foo() { i = 0; // OK this->i = 0; // OK B *pb = this; pb->i = 0; // OK A *pa = this; pa->i = 0; // ERROR ((A *) this)->i = 0; // ERROR } };
In the above B::foo
, you can access base member A::i
by using just plain i
syntax. This is equivalent to using this->i
syntax. Both will work, because the pointer this
has type B *
, i.e. you are accessing A::i
thorough a pointer of type B *
. This is exactly what the protected
access specifier is supposed to allow. The access through pb
pointer works for the very same reason.
However, when you "convert" this
pointer to type A *
, you can no longer access A::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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With