C++98环境下如何将基类赋值运算符引入派生类
C++98 环境下派生类隐藏基类赋值运算符的解决方案
问题原因
派生类进行名字查找时,会优先检索自身作用域的成员名。编译器为派生类隐式生成的拷贝赋值运算符会直接隐藏基类中所有同名的operator=,哪怕基类赋值运算符的参数列表和派生类隐式赋值运算符完全不匹配,也不会进入重载候选集,最终触发编译错误。
C11 标准允许通过using 基类名::operator=的声明,将基类的赋值运算符重载全部引入派生类作用域参与重载匹配,但该特性在C98中不支持:C++98 标准明确规定,using声明不能将基类的赋值运算符纳入派生类的赋值运算符重载集,即使手动写了using声明也无法解决隐藏问题。
C++98 标准下的常规实现方式
C++98 没有批量引入基类赋值运算符的语法,最通用的做法是在派生类中显式定义需要对外暴露的赋值运算符重载,内部直接转发调用基类的对应实现。
针对给出的示例代码,修复方式如下:
template <typename T> struct B { B &operator=(const T &) { return *this; } }; struct D : B<int> { // 显式定义int参数版本的赋值运算符,转发到基类实现 D &operator=(const int &rhs) { B<int>::operator=(rhs); return *this; } }; int main() { D d; d = 0; // 正常编译 return 0; }
实现注意事项
- 转发函数的返回值需要定义为派生类类型的引用,遵循C++赋值运算符的常规语义,支持链式赋值写法。
- 如果基类存在多个不同参数的
operator=重载,需要在派生类中为每一个需要暴露的重载单独编写转发逻辑,没有批量导入的语法捷径。 - 手动编写的参数为其他类型的赋值运算符,不会干扰编译器为派生类隐式生成默认拷贝赋值运算符,二者属于重载关系,互不影响。
内容的提问来源于stack exchange,提问作者PaperBirdMaster
相关产品推荐
相关产品推荐

