【问题标题】:c++ Overload operator in abstract classc ++抽象类中的重载运算符
【发布时间】:2014-02-28 11:09:42
【问题描述】:

我有如下界面:

class A
{
  public:
    virtual A * operator+(const A &rhs) const = 0;
}

还有抽象类:

class B : public A
{
  public:
    B(int val)
    {
      this->val = val;
    }

    virtual A * operator+(const A &rhs) const
    {
      return (new B(this->val + rhs.val));
    }
    int val;
}

另外,我有这个课:

class C
{
  public:
    void add();
  private:
    std::stack<A *> Astack;
}

不能修改operator+原型。

我的问题是我无法创建添加功能。我试过这个:

void    C::add()
{
  B first = *dynamic_cast<B *>(this->Astack.top()); // Error here
  this->Astack.pop();
  B second = *dynamic_cast<B *>(this->Astack.top()); // And here
  this->Astack.pop();
  B * res = first + second;
  this->Astack.push(res);
}

但是我的编译器告诉我: 错误:无法在初始化中将B 转换为A *。 事实上,我无法获取到B添加它们。

【问题讨论】:

  • 不要以这种方式实现运算符重载。请注意,您的添加已泄漏(考虑像 a + b + c 这样的表达式,它会生成两个临时变量:它至少泄漏一个临时变量)
  • 我不得不这样做,这是学校的练习
  • 好的,告诉你的老师不要把 C++ 当作 Java。在这种情况下,多态运算符重载根本没有意义。只需针对不同的情况实现不同的重载。 C++ 依赖于鸭子类型来处理这类事情:如果类型 TU 存在 operator+ 重载,则认为 TU 是可添加的。您不提供额外的多态接口并让实现该接口的类被认为是可添加的。
  • 是因为这个原因我得到了 -1 吗?
  • 是的,它是我的。但不要难过:这真的是对你的老师的一票否决。请给他看这个帖子。

标签: c++ class interface casting


【解决方案1】:

操作员不能是虚拟的(好吧,从技术上讲,他们可以,但这是灾难的根源,导致客户端代码中出现切片、奇怪的算术表达式以及对可爱的小海豹的无端谋杀)。

您的C::add 应该与此类似:

void C::add() // assuming implementation is supposed to sum instances and 
              // add replace the contents of Astack with the sum
{
    A* x = Astack.top();
    Astack.pop();
    while(!Astack.empty()) {
        A* y = Astack.top();
        Astack.pop();

        A* z = (*x) + (*y);
        delete x;
        delete y;

        x = z; // latest result will be in x on the next iteration
    }
    Astack.push(x);
}

此外,您的老师应该了解不滥用内存分配、不滥用虚函数、不强加虚运算符以及 C++ 类接口设计中的好坏做法 - 包括重载算术运算符的正确函数签名。

【讨论】:

    【解决方案2】:

    firstsecond 都是指针变量和持有地址。你不能添加两个地址。

    first + second 不是在调用你的运算符重载函数,请尝试使用*first + *second

    【讨论】:

    • 在OP例子中,first和second是Stack变量,所以算子调用是正确的。
    • @MatthiasBonora 问题在我发帖后被修改。
    【解决方案3】:
    B * res = first + second;  // Error here !
    

    在这里,您尝试将 A* 指针(由 operator+ 返回)分配给 B* 指针。你必须投射结果。类似的东西:

    B * res = dynamic_cast<B*>(first + second);
    

    编辑:并不是说您应该以这种方式使用运算符重载。 utnapistim 对此给出了很好的回答。

    【讨论】:

      猜你喜欢
      • 2012-06-16
      • 2021-11-13
      • 1970-01-01
      • 1970-01-01
      • 2016-07-15
      • 1970-01-01
      • 2018-02-22
      • 1970-01-01
      • 2015-05-09
      相关资源
      最近更新 更多