C++继承构造函数using声明编译错误问题咨询
构造函数继承的访问权限问题分析
先看你给出的报错代码:
class Shape { protected: Shape() : num(0) {} Shape(int i) : num(i) {} public: int getNum() const { return num; } private: int num; }; struct Lines : Shape { using Shape::Shape; }; int main() { Lines l; // OK Lines l2(10); // error here }
对应的报错信息:
- E0330 "Lines::Shape(int i)" (declared implicitly) is inaccessible
- C2248 'Lines::Lines': cannot access protected member declared in class 'Lines'
错误原因拆解
核心问题在于C++构造函数继承的访问权限规则:
当你在派生类中用using Shape::Shape;声明继承基类的构造函数时,这些构造函数在派生类中的访问权限和基类中完全一致,不会因为派生类的默认访问权限(struct默认public)而改变。
在你的代码里:
- 基类
Shape的带参构造函数Shape(int i)是protected权限,所以通过using继承到Lines后,这个构造函数在Lines中仍然是protected的。而main函数属于类外部作用域,无法访问类的protected成员,因此调用Lines l2(10)会触发权限错误。 - 为什么
Lines l;可以正常编译?因为这里调用的是编译器为Lines自动生成的public默认构造函数——这个生成的构造函数内部会调用基类的protected默认构造函数,而派生类的成员(包括编译器生成的构造函数)有权访问基类的protected成员,所以这是合法的。
对比书中代码的差异
你提到的《Programming: Principles and Practice Using C++, 2nd Edition》中的代码:
struct Open_polyline : Shape { // open sequence of lines using Shape::Shape; // use Shape’s constructors (§A.16) void add(Point p) { Shape::add(p); } }; class Shape { // deals with color and style and holds sequence of lines // ... 其他成员 ... protected: Shape() { } Shape(initializer_list<Point> lst); // add() the Points to this Shape // ... 其他成员 ... }; Open_polyline opl = { {100,100}, {150,200}, {250,250}, {300,200} };
这段代码能正常运行的关键在于:它使用的是聚合初始化(C++17及以后允许聚合类继承public基类),而非直接调用继承的protected构造函数。编译器会通过聚合初始化的规则,间接完成基类的初始化,绕开了直接访问protected构造函数的限制。
解决方法
如果你需要在外部调用派生类的带参构造函数,不要用using继承基类的protected构造函数,而是在派生类中显式定义一个public的构造函数,内部调用基类的构造函数:
struct Lines : Shape { Lines() = default; // 可选,编译器会自动生成 Lines(int i) : Shape(i) {} // 显式定义public构造函数 };
内容的提问来源于stack exchange,提问作者marikocat
相关产品推荐
相关产品推荐

