关于受保护构造函数的一个问题。我了解到受保护的构造函数可以在派生类中使用。但是,我发现下面的代码有错误。为什么会这样?
class A
{
protected:
A(){}
};
class B: public A {
public:
B() {
A* f=new A(); // Why it is not working here
}
};
答案 0 :(得分:41)
这与构造函数无关。这就是protected
访问权限的工作方式。
protected
访问说明符的工作方式,它允许派生类B
仅在类{{}的对象时访问基类A
的对象的内容1}}是类A
的子对象。这意味着您在代码中唯一能做的就是通过 B
访问A
的内容:您可以通过访问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
,即您通过B *
类型的指针访问A::i
。这正是B *
访问说明符应允许的内容。通过protected
指针进行访问的原因完全相同。
但是,当您将pb
指针“转换”为this
类型时,即使您仍在尝试访问它们,也无法再通过该新指针访问A *
会员和以前一样。
当应用于构造函数时,A::i
访问说明符具有非常特定的效果:受保护的构造函数只能用于初始化基类子对象。它不能用于初始化独立对象(这是您尝试执行的操作)。换句话说,受保护的构造函数是在C ++中实现抽象类概念的另一种方法(以及纯虚方法)。如果您的类的构造函数受到保护,那么您的类实际上是 abstract 。您不能使用它来“从外部”定义独立对象。 (当然,以上内容并不适用于朋友,也不适用于班级内部。)
答案 1 :(得分:6)
当基类具有受保护的构造函数时,您无法直接实例化该类。但是你可以这样做从基类构造函数中调用构造函数:
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 ++中声明构造函数 protected ,则无法创建该实例除了通过继承或朋友关系以外的类。
答案 2 :(得分:0)
让我按顺序回答:
1)构造函数没有得到继承,为什么在派生类中,它们不能被覆盖 2)调用构造函数而不调用构造函数 3)如果你在A中声明了一个简单的函数,说出protected void print(),然后尝试在B中调用它,那就可以了。这种情况发生在bcoz,B继承了这个功能。
4)当你做这样的事情时b:a(),你正在调用构造函数,这是允许的。
5)尝试使B成为A的朋友类,然后运行并查看它是否有效。
希望这有帮助。
答案 3 :(得分:0)
我有同样的问题,this link让我明白。
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)