operator =在抽象类层次结构中的棘手继承

时间:2014-06-12 08:04:42

标签: c++ inheritance c++11 operator-overloading abstract

我有这个类层次结构,我试图添加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

我尝试过dynamic_cast o来输入B,但是

  1. 因为它不变而无法工作,
  2. 看起来不安全(如果rhs是C型)
  3. C类相同的问题 是否有一些切割工具?

    通过这种方式澄清我为什么需要它:

    class superClass
    {
    public:
      superClass& operator=(const superClass& o)
      {
        *some_A_type = *o.some_A_type;
      }
    private:
      A* some_A_type;
    };
    
    基本上,我想要的是一个operator = for superClass。我不知道在哪里或如何解决它。

2 个答案:

答案 0 :(得分:0)

在Tobi McNamobi建议的similiar问题中找到:

class B : public A
{
public:
  virtual A& operator=(const A& p)
  {
    *ptr = *o.ptr;
    return *this;
  }


  virtual B& operator=(const B& p)
  {
    //throw exception
  }

};

答案 1 :(得分:0)

您应该重新考虑您的初始设计课程。

你也应该明白:

  • 运算符多态性(a + b适用于std::stringint
  • 数据类型本身不能是多态的,因为应该定义内存布局
  • 什么是抽象类和/或接口
  • 也许静态多态也很有用

首先尝试想象在类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;
};

P.S。最后的变种在现实世界中可能是不受欢迎的。