为什么我不能使用 protected/private 继承在派生实例中访问基 class 的受保护成员?
Why can't I access protected members of base class in derived instances using protected/private inheritance?
我认为 Base class 的受保护成员可以被 Derived class 的实例(或派生自 Derived class 的任何 class 实例访问,因为他们公开继承了后者)。
但是我在尝试在以下列表中执行此操作时遇到错误。那我错过了什么?
class Base{
private:
virtual void f(){cout << "f of Base" << endl;}
public:
virtual ~Base(){}
virtual void g(){this->f();}
virtual void h(){cout << "h of Base "; this->f();}
};
class Derived: protected Base{
public:
virtual ~Derived(){}
virtual void f(){cout << "f of Derived" << endl;}
private:
virtual void h(){cout << "h of Derived "; this->f();}
};
int main(){
Base *base = new Base();
cout << "Base" << endl;
base->g(); //f of Base
base->h(); //h of Base f of Base
Derived *derived = new Derived();
cout << "Derived" << endl;
derived->f(); //f of Derived
derived->g(); //this doesn't compile and I get the error "void Base::g() is inaccessible within this context". Why?
derived->h(); //this doesn't compile given that h is private in Derived
delete base;
delete derived;
return EXIT_SUCCESS;
}
因为 Derived
继承自 Base
protected
ly,Base
的所有 public 成员都是 Derived
中的 protected
.这意味着,在 Derived
之外(例如在 main
中),这些成员的名字是不可见的。
[class.access.base]/1
[...] If a class is declared to be a base class for another class using the protected
access specifier, the public and protected members of the base class are accessible as protected members of the derived class. [...]
[class.access]/1.2
A member of a class can be
(1.2) protected; that is, its name can be used only by members and friends of the class in which it is declared, by classes derived from that class, and by their friends (see [class.protected]).
当您声明 protected
由 Derived
继承 Base
时,如下所示
class Derived: protected Base
您基本上是在创建派生 class 的 Base
class protected
成员的任何 public 方法。如果您改为通过
将继承声明为 public
class Derived: public Base
您会发现您可以正常访问 derived->g()
。
derived->g();
可以通过将继承更改为 public 来访问。
derived->h();
可以通过将派生 class 中的访问说明符从私有更改为 public 来访问(仍将继承保持为受保护,因为派生 class 指针指向其成员函数)
我认为 Base class 的受保护成员可以被 Derived class 的实例(或派生自 Derived class 的任何 class 实例访问,因为他们公开继承了后者)。
但是我在尝试在以下列表中执行此操作时遇到错误。那我错过了什么?
class Base{
private:
virtual void f(){cout << "f of Base" << endl;}
public:
virtual ~Base(){}
virtual void g(){this->f();}
virtual void h(){cout << "h of Base "; this->f();}
};
class Derived: protected Base{
public:
virtual ~Derived(){}
virtual void f(){cout << "f of Derived" << endl;}
private:
virtual void h(){cout << "h of Derived "; this->f();}
};
int main(){
Base *base = new Base();
cout << "Base" << endl;
base->g(); //f of Base
base->h(); //h of Base f of Base
Derived *derived = new Derived();
cout << "Derived" << endl;
derived->f(); //f of Derived
derived->g(); //this doesn't compile and I get the error "void Base::g() is inaccessible within this context". Why?
derived->h(); //this doesn't compile given that h is private in Derived
delete base;
delete derived;
return EXIT_SUCCESS;
}
因为 Derived
继承自 Base
protected
ly,Base
的所有 public 成员都是 Derived
中的 protected
.这意味着,在 Derived
之外(例如在 main
中),这些成员的名字是不可见的。
[class.access.base]/1
[...] If a class is declared to be a base class for another class using the
protected
access specifier, the public and protected members of the base class are accessible as protected members of the derived class. [...]
[class.access]/1.2
A member of a class can be
(1.2) protected; that is, its name can be used only by members and friends of the class in which it is declared, by classes derived from that class, and by their friends (see [class.protected]).
当您声明 protected
由 Derived
继承 Base
时,如下所示
class Derived: protected Base
您基本上是在创建派生 class 的 Base
class protected
成员的任何 public 方法。如果您改为通过
class Derived: public Base
您会发现您可以正常访问 derived->g()
。
derived->g();
可以通过将继承更改为 public 来访问。
derived->h();
可以通过将派生 class 中的访问说明符从私有更改为 public 来访问(仍将继承保持为受保护,因为派生 class 指针指向其成员函数)