Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
262 views
in Technique[技术] by (71.8m points)

c++ - Why is protected constructor raising an error this this code?

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
        }
};
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...