C++98中通过基类实例构造/赋值派生类是否需新增对应函数
问题相关代码定义
给出的基类A、派生类B初始实现代码如下:
class A { public: A(void) : i(0) {} A(int val) : i(val) {} A(const A& other) : i(other.i) {} A& operator=(const A& other) { i = other.i; return *this; } int i; }; class B : public A { public: B(void) : A(), j(0) {}; B(const B& other) : A(other), j(other.j) {} // 注意:原实现此处存在编译错误,初始化列表引用了未定义的other标识符,正确写法应为B(int i, int j) : A(i), j(j) {} B(int i, int j) : A(other.i), j(other.j) {} B& operator=(const B& other) { A::operator=(other); j = other.j; return *this; } int j; };
核心疑问
已知B类已实现拷贝构造函数与operator=赋值运算符重载,若需要实现两个操作:
- 通过已初始化的A类实例创建B类实例
- 将已有A类实例赋值给已存在的B类实例
是否需要为B类额外定义如下签名的构造函数与赋值运算符重载:
B(const A& other); B& operator=(const A& other);
约束条件:
- 实现目标:仅依靠基类信息完成派生类实例的实例化与赋值操作
- 编译环境:使用C98标准,不可使用更高版本C特性
结论
必须额外定义上述两个签名的函数,现有B类实现无法支持对应操作,原因如下:
- C++98标准下不存在基类到派生类的隐式转换:派生类比基类多出独立成员(本示例中B类比A类多了成员
j),编译器无法自动推导派生类独有成员的初始化/赋值逻辑,不会自动生成接收基类类型参数的构造函数、赋值运算符。 - 现有B类的接口无法匹配传入A类实例的场景:现有构造函数仅支持无参、B类实例拷贝、两个int参数传入三种初始化方式;现有赋值运算符仅支持接收B类实例参数,传入A类实例时没有匹配的函数签名,会直接编译报错。
C++98兼容实现参考
按照仅使用基类信息的需求,新增两个函数的实现可以参考如下写法(派生类独有成员j初始化为默认值0,可根据实际业务需求调整赋值逻辑):
class B : public A { public: B(void) : A(), j(0) {}; B(const B& other) : A(other), j(other.j) {} B(int i, int j) : A(i), j(j) {} // 修正原代码的编译错误 // 新增:接收A类实例的构造函数 B(const A& other) : A(other), j(0) {} // 原有B类拷贝赋值 B& operator=(const B& other) { A::operator=(other); j = other.j; return *this; } // 新增:接收A类实例的赋值运算符 B& operator=(const A& other) { A::operator=(other); j = 0; // 若需要保留B实例原有j的值,删除此行即可 return *this; } int j; };
补充说明:上述重载符合C++98的重载匹配规则,当传入参数为B类型时,会优先匹配参数为const B&的版本,不会影响原有B类实例的拷贝、赋值逻辑。
内容的提问来源于stack exchange,提问作者carce-bo
相关产品推荐
相关产品推荐

