关于受保护构造函数的一个问题。我了解到受保护的构造函数可以在派生类中使用。但是,我发现下面的代码有错误。为什么会这样?
class A
{
protected:
A(){}
};
class B: public A {
public:
B() {
A* f=new A(); // Why it is not working here
}
};
关于受保护构造函数的一个问题。我了解到受保护的构造函数可以在派生类中使用。但是,我发现下面的代码有错误。为什么会这样?
class A
{
protected:
A(){}
};
class B: public A {
public:
B() {
A* f=new A(); // Why it is not working here
}
};
这与构造函数无关。这就是protected
访问的工作方式。
访问说明符的工作方式protected
,它允许派生类B
访问基类对象的内容,A
只有当类A
的对象是类的子对象时B
。这意味着您在代码中唯一能做的就是访问A
through 的内容:您可以通过 type 的指针(或 type 的引用)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
}
};
在上面B::foo
,您可以A::i
使用简单的i
语法访问基本成员。这相当于使用this->i
语法。两者都可以,因为指针this
具有 type B *
,即您正在访问A::i
一个 type 的指针B *
。这正是protected
访问说明符应该允许的。通过pb
指针访问也是出于同样的原因。
但是,当您将this
指针“转换”为 typeA *
时,您将无法再A::i
通过该新指针进行访问,即使您仍在尝试访问它们与以前相同的成员。
当应用于构造函数时,protected
访问说明符具有非常特殊的作用:受保护的构造函数只能用于初始化基类子对象。它不能用于初始化独立对象(这是您尝试做的)。换句话说,受保护的构造函数是在 C++ 中实现抽象类概念的另一种方式(以及纯虚方法)。如果您的类的构造函数受到保护,那么您的类实际上是abstract。您不能使用它来“从外部”定义独立对象。(当然,以上不适用于朋友,也不适用于班级本身)。
当基类具有受保护的构造函数时,您不能直接实例化该类。但是您可以这样做以从基类构造函数调用构造函数:
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!
}
};
如下所示直接调用构造函数会在 gcc 版本 4.1.2 中为您提供以下错误:
A* f = new A(); // Not allowed to access constructor like this!
test.cpp:4: error: A::A() is protected
但是,您对构造函数的此调用没有给出错误:
B() : A() // allowed to access constructor like this
这背后的原因是第二次调用通过继承访问 A() 构造函数,这是允许的。但是,这会尝试通过直接调用构造函数来显式创建 A() 的新实例:
A* f = new A(); // Not allowed to access constructor like this!
这可能看起来不直观,因为 B 应该能够访问 A 的构造函数,因为 B 继承自 A。但是,如果您在 C++ 中声明了受保护的构造函数,则无法创建该类的实例,除非通过继承或朋友关系。
让我分步回答:
1)构造函数不会被继承,这就是为什么在派生类中,它们不能被覆盖。
2) 构造函数被调用而不被调用。
3) 如果你在 A 中声明了一个简单的函数,比如 protected void print(),然后尝试在 B 中调用它,它就会起作用。这发生在 bcoz 中,B 继承了这个函数。
4) 当您执行类似 b : a() 的操作时,您正在调用构造函数,这是允许的。
5)尝试让 B 成为 A 的朋友类,然后运行,看看它是否有效。
希望这可以帮助。
我有同样的问题,这个链接让我很清楚。
cppreference是这样说的:
Protected members form the interface for the derived classes (which is
distinct from the public interface of the class).
A protected member of a class Base can only be accessed
1) by the members and friends of Base
2) by the members and friends (until C++17) of any class derived from Base, but only when operating on an object of a type that is derived from Base (including this)