为何C++派生类无法继承基类的赋值运算符?
为什么派生类无法调用基类的赋值运算符?
问题描述
以下代码中,基类B定义了接受int的赋值运算符和foo成员函数,派生类D继承自B。调用b=2和b.foo(2)都正常,但d=2无法编译,而d.foo(2)却可以正常运行,这是为什么?
#include <iostream> struct B { void operator=(int) { std::cout << "B=int\n"; } void foo(int) { std::cout << "foo\n"; } }; struct D : B { }; int main() { B b; D d; b=2; b.foo(2); // d=2; // <-- 这行无法编译 d.foo(2); }
原因分析
这是因为赋值运算符的特殊性:
- 对于普通成员函数(比如
foo),如果派生类没有定义同名函数,编译器会自动在基类中查找匹配的函数,所以d.foo(2)能正常调用基类的foo(int)。 - 但赋值运算符不一样:编译器会为派生类
D自动生成一个默认拷贝赋值运算符,签名为D& operator=(const D&)。这个自动生成的运算符会隐藏基类中所有同名的operator=。当你尝试执行d=2时,编译器只会在D的作用域内查找operator=,找到的只有这个默认生成的拷贝赋值,而int类型无法隐式转换为const D&,因此编译报错。
解决方法
如果想让派生类能调用基类的operator=(int),可以在派生类中使用using声明将基类的赋值运算符引入到当前作用域,避免被隐藏:
struct D : B { using B::operator=; // 引入基类的所有operator= };
这样d=2就会匹配到基类的void operator=(int),正常编译运行。
内容的提问来源于stack exchange,提问作者Baruch
相关产品推荐
相关产品推荐

