sky*_*oor 29 c++ constructor protected
关于受保护构造函数的一个问题 我了解到受保护的构造函数可以在派生类中使用.但是,我发现下面的代码有错误.为什么会这样?
class A
{
protected:
A(){}
};
class B: public A {
public:
B() {
A* f=new A(); // Why it is not working here
}
};
Run Code Online (Sandbox Code Playgroud)
AnT*_*AnT 42
这与构造函数无关.这就是protected访问的工作原理.
的方式protected访问指示符的工作原理,它允许派生类B访问基类的一个对象的内容A 只有当类的该对象A是类的一个子对象B.这意味着您在代码中唯一能做的就是访问A through 的内容B:您可以A通过类型指针B *(或类型的引用B &)访问成员.但是您无法通过类型A *(或引用A &)的指针访问相同的成员.
请考虑以下示例
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
}
};
Run Code Online (Sandbox Code Playgroud)
在上面B::foo,您可以A::i使用简单的i语法访问基本成员.这相当于使用this->i语法.两者都可以工作,因为指针this有类型B *,即你通过A::i类型的指针访问B *.这正是protected访问说明符应该允许的内容.通过pb指针访问的原因完全相同.
但是,当您将this指针"转换" 为类型时A *,A::i即使您仍在尝试访问与之前完全相同的成员,也无法再通过该新指针进行访问.
当应用于构造函数时,protected访问说明符具有非常特定的效果:受保护的构造函数只能用于初始化基类子对象.它不能用于初始化独立对象(这是您尝试执行的操作).换句话说,受保护的构造函数是在C++中实现抽象类概念的另一种方法(以及纯虚方法).如果你的类的构造函数受到保护,那么你的类就是有效的抽象.您不能使用它来"从外部"定义独立对象.(当然,以上内容不适用于朋友,也不适用于班级内部).
当基类具有受保护的构造函数时,您无法直接实例化该类.但是你可以这样做从基类构造函数中调用构造函数:
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!
}
};
Run Code Online (Sandbox Code Playgroud)
如下所示直接调用构造函数会使gcc版本4.1.2出现以下错误:
A* f = new A(); // Not allowed to access constructor like this!
test.cpp:4: error: A::A() is protected
Run Code Online (Sandbox Code Playgroud)
但是,您对构造函数的调用没有错误:
B() : A() // allowed to access constructor like this
Run Code Online (Sandbox Code Playgroud)
这背后的原因是第二个调用通过继承访问A()构造函数,这是允许的.但是,这会尝试通过直接调用构造函数显式创建A()的新实例:
A* f = new A(); // Not allowed to access constructor like this!
Run Code Online (Sandbox Code Playgroud)
这可能看起来不直观,因为B应该能够访问A的构造函数,因为B继承自A.但是,如果声明在C++中受保护的构造函数,则除了通过继承或朋友关系之外,不能创建该类的实例.
| 归档时间: |
|
| 查看次数: |
13632 次 |
| 最近记录: |