c++ - 在派生类中重写二进制运算符

标签 c++ inheritance overloading operator-keyword

目前,我正在研究一些代数问题。我有一个(几乎抽象的)基类,将从中派生几个类。所有这些类将包含数字列表,这些数字以许多非常不同的方式排序。
在基类上,我想定义一些将为每个派生类实现的运算符。这个想法是,一旦该库完成,我就不必再关心派生类的内在函数了。初始化某个派生类后,可以通过基本类型的引用(或指针)并通过访问所有派生操作来引用它。

我想根据在基类上定义的操作来设置相当复杂的算法。因此,我希望只能通过基类访问这些算法。这样,它应该很容易地概括为许多类型的派生类。
我知道这正是面向对象编程的目的,所以这就是我最终使用C++的原因。

我已经以与本示例类似的方式设置了我想要的大多数东西(适用于g++):

#include <iostream>
class base;
base & gettype(const base&);
class base{
    public:
    int x;
    int type;
    base() = default;
    base(int in){
        this->type=0;
        this->x = in;
    }
    virtual base & operator+= ( const base & other){
        this->x += other.x;
        return *this;
    }
    virtual base & operator+ ( const base & other){
        base & ret = gettype(*this);
        ret += other.x;
        return ret;
    }
    virtual void print(){
        std::cout << "base is: " << x << "\n";
    }
};
class der1:public base{
    public:
    int a;
    der1(){}
    der1(int in){
        this->x = in;
        this->a = 2*in;
        this->type=1;

    }
    base & operator+= ( const base & other){
        std::cout <<"used der add\n";
        const der1 & otherder = static_cast<const der1 &>(other);
        this->x += otherder.x;
        this->a += otherder.a;
        return *this;
    }
    void print(){
        std::cout << "der1 is: " << x << " " << a << "\n";
    }
};
base & gettype(const base & in){
    if(in.type==0){
        return * new base();
    }
    if(in.type==1){
        return * new der1();
    }
}

main(){
    base baseobj(2);
    baseobj.print();
    baseobj += baseobj;
    baseobj.print();
    (baseobj+baseobj).print(); //Answer is right, but there is a memory leak

    der1 derobj(3);
    derobj.print();
    derobj += derobj;
    base * test = new der1(4);
    test->print();
    (*test) += (*test);
    test->print();
    base & test2 = *test;
    test2 += test2;
    test2.print(); //All these print the right answers as well
    delete test; 
}

但是里面有内存泄漏。每当我执行类似x=x+y的操作时,在gettype函数中分配的内存就不再释放。

我已经读过,让operator+函数返回引用是相当罕见的。但是,当operator+按值返回时,我不能令人满意地完成这项工作。原因是当按值返回时,它将返回切成base对象的对象。当我用协变类型定义派生的operator+函数时(如下面的示例所示),将不使用它们,因为我仅使用base类型引用,而不是der1
#include <iostream>
class base{
    public:
    int x;
    base() = default;
    base(int in){
        this->x = in;
    }
    virtual base & operator+= ( const base & other){
        this->x += other.x;
        return *this;
    }
    virtual base operator+ ( const base & other){
        base ret(*this);
        ret += other.x;
        return ret;
    }
    virtual void print(){
        std::cout << "base is: " << x << "\n";
    }
};
class der1:public base{
    public:
    int a;
    der1(int in){
        this->x = in;
        this->a = 2*in;
    }
    der1 & operator+= ( const der1 & other){
        this->x += other.x;
        this->a += other.a;
        return *this;
    }
    der1 operator+ ( const der1 & other){
        der1 ret(*this);
        ret += other.x;
        return ret;
    }
    void print(){
        std::cout << "der1 is: " << x << " " << a << "\n";
    }
};

main(){
    base baseobj(2);
    baseobj.print();
    baseobj += baseobj;
    baseobj.print();
    (baseobj+baseobj).print();  //This all works nicely for the base class

    der1 derobj(3);
    derobj.print();
    base * test = new der1(4);
    test->print(); //derived print function
    base & test2 = *test;
    test2 += test2; //base add function, because argument base&
    test2.print(); //Indeed, wrong answer.

}

因此有可能创建一个我可以以类似方式使用的库:
base & x = getderived(3) // This will return a (reference/pointer to) derived type
base & y = getderived(3)
x +=y;
x = x+3*y;
//And a whole lot of other operations

delete x
delete y // I don't mine some manual memory management

我希望我要实现的目标很明确。如果您认为这是不可能的,那么我也很乐意回答这个问题,那么我知道我必须停止进一步寻找。 (如果没有解决方案,我将保留当前的方法,并且必须像运算符一样使用+=,并跳过二进制的。这并不完全不好)

最佳答案

在C++中,永远不要使用显式的new / delete,而应该遵循 RAII

如果我理解您的问题,我将摆​​脱typegettype,而使用虚拟的clone:

class base
{
public:
    virtual std::unique_ptr<base> clone() const
    {
        return std::make_unique<base>(*this);
    }
};

class derived : public base
{
public:
    std::unique_ptr<base> clone() const override
    {
        return std::make_unique<derived>(*this);
    }
};

关于c++ - 在派生类中重写二进制运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62063918/

相关文章:

python - 使用 boost::python 时将 python.io 对象转换为 std::istream

C++ 数组虽然通过引用传递但没有改变

c++ - C++中对象的继承和双端队列

java - 比较类类型与继承

wcf - 具有不同签名的相同方法的推荐命名约定?

c++ - 使用 C++ 进行 strtok 拆分时出错

c++ - Fork Direct Show 三通过滤器

C++ 继承(覆盖构造函数)

c# - 如何在工厂中重载通用 C# 方法?

c++ - 将类对象转换为字符串