在抽象类层次结构中操作符=的复杂继承
Tricky inheritance of operator= in abstract class hierarchy
我有这个类层次结构,我试图添加operator=:
class A
{
public:
virtual void someFunction() = 0;
virtual A& operator=(const A&) = 0;
};
class B : public A
{
public:
void someFunction() {
//implementation
}
A& operator=(const A& o)
{
*ptr = *o.ptr;
return *this;
}
private:
A* ptr;
};
class C : public A
{
public:
void someFunction() {
//implementation
}
A& operator=(const A& o)
{
data = o.data;
return *this;
}
private:
int data; //NOTE: different members that needs to be copied in the operator
};
我明白为什么这不起作用。我在B中有一个私有成员(它需要在那里)和一个需要重写的函数A&operator=(const A&)
。问题是o
是A型的,没有指针ptr
。
我已经尝试将0动态转换为类型B,但是
- 不能工作,因为它是常量,
- 似乎不安全(如果rhs是C类)
C类也有同样的问题。有什么切菜刀的办法吗?
解释为什么我需要这样做:
class superClass
{
public:
superClass& operator=(const superClass& o)
{
*some_A_type = *o.some_A_type;
}
private:
A* some_A_type;
};
实际上,我想要的是superClass的操作符=。我不确定在哪里或如何修复它
你应该重新考虑你最初的类设计。
你也应该明白:
- 操作符多态性(
a + b
适用于std::string
和int
) - 数据类型本身不能为polymorph,因为应该定义内存布局 什么是抽象类和/或接口
- 也许静态多态性也会有用
首先试着想象在A
类的任意类的任意对象之间赋值意味着什么。也就是说,为了将B
的对象存储在C
的对象中,我们应该改变C
对象的状态,使其特征等同于B
的原始对象。这可以通过在A
的所有后代之间拥有共同的内存布局(即所有后代存储相同的数据)或通过引用原始对象等其他方式暴露相同的行为来实现。
注意virtual void someFunction()
的行为也应该被复制。
让我们试着最大限度地利用你的样品:
// our interface
struct A {
virtual void someFunction() = 0;
// no polymorphic assignment
};
struct B : A {
void someFunction();
B &operator=(const A &o)
{ ptr = &o; return *this; }
private:
A *ptr;
}
struct C : A {
void someFunction();
A &operator=(const C &o)
{ data = o.data; return *this; }
private:
int data;
};
C c, c2;
B b;
A &a = c;
b = c; // ok
b = a; // ok
c = c2; // ok
c = b; // wrong
或者如果你仍然想要多态分配:
// interface. descendants are responsible for maintaining LSP
struct A {
void someFunction()
{ cout << data(); }
virtual int getData() const = 0;
// assignment should result in copying chars and making getData() to behave like in original object
virtual A &operator=(const A &o) = 0;
};
struct B : A {
int getData() const { return ptr->getData(); }
A &operator=(const A &o)
{ ptr = &o; return *this; }
private:
const A *ptr;
};
struct C : A {
int getData() const { return data; }
A &operator=(const A &o)
{ data = o.getData(); return *this; }
private:
int data;
};
注:最后一个在现实世界中可能不需要的变体
在toimcnamobi提出的类似问题中找到:
class B : public A
{
public:
virtual A& operator=(const A& p)
{
*ptr = *o.ptr;
return *this;
}
virtual B& operator=(const B& p)
{
//throw exception
}
};
相关文章:
- 继承函数的重载解析
- 继承期间显示未知行为的子类
- 函数复杂度分析
- 头文件-继承c++
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- 为什么在保护模式下继承升级不起作用
- while循环中while循环的时间复杂度是多少
- 通过继承类使用来自不同命名空间的运算符
- 子目录是否继承属性,例如add_definitions,include_directories和父Cmakelist.t
- 混合组合和继承的C++问题
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 从类继承时,继承的类是否会通过父类重新定义继承的变量
- 公共与私人继承
- 如何在复杂继承中访问静态成员变量
- 复杂的钻石问题:C++虚拟继承
- 访问受保护的变量 - 继承和子类的复杂情况
- 重写复杂继承层次结构的每个类的初始化列表
- 在抽象类层次结构中操作符=的复杂继承
- 如何专门化具有继承的复杂模板- c++
- 在复杂的继承中C++模板