简体   繁体   English

C++ 加法运算符重载多次

[英]C++ addition operator overloading multiple times

i am trying to get some mathematical construct working which contains 'Cells' which represent a mathematical function with a set of inputs and outputs.我试图让一些数学构造工作,其中包含“单元”,它代表具有一组输入和输出的数学 function。

Each mathematical operation gets their own class which inherits from Cell .每个数学运算都有自己的 class 继承自Cell Using some operator overloading, I would like to spawn a new Add -Cell when i call operator+ on two cells.使用一些运算符重载,当我在两个单元格上调用operator+时,我想生成一个新的Add -Cell。

This works fine so far but I encountered a problem.到目前为止,这工作正常,但我遇到了一个问题。

I have written a small demo code which illustrates my problem:我写了一个小演示代码来说明我的问题:

Imagine this class which fully implements copy/move assignment/construction as well as a custom destructor and a constructor.想象一下这个 class 完全实现了复制/移动分配/构造以及自定义析构函数和构造函数。


class Cell{

private:
    Cell* A = nullptr;
    Cell* B = nullptr;
public:
    Cell() {
        std::cout << "default constructed" << std::endl;
    }
    Cell(Cell& A, Cell& B) {
        this->A = &A;
        this->B = &B;
        std::cout << "default constructed" << std::endl;
    }
    T(const Cell& other){
        this->A = other.A;
        this->B = other.B;
        std::cout << "copy constructed" << std::endl;

    }
    T(Cell&& other){
        this->A = other.A;
        this->B = other.B;
        std::cout << "move constructed" << std::endl;

    }
    Cell& operator=(Cell&& other){
        this->A = other.A;
        this->B = other.B;
        std::cout << "move assigned" << std::endl;
        return *this;

    }
    Cell& operator=(const Cell&& other){
        this->A = other.A;
        this->B = other.B;
        std::cout << "copy assigned" << std::endl;
        return *this;
    }

    Cell operator+(Cell& other){
        return T{*this, other};
    }

    virtual ~Cell() {
        std::cout << "destructed" << std::endl;
    }

};

It is similar to my code.它类似于我的代码。 Here Cell can be considered any type of cell with 2 previous mathematical operations.这里的Cell可以被认为是具有 2 个先前数学运算的任何类型的单元。

So the issue arises when I try to do something like this:所以当我尝试做这样的事情时,问题就出现了:

    Cell t1{};
    Cell t2{};
    Cell t3{};

    auto h = t1 + t2 + t3;

It creates 3 empty Cell objects.它创建了 3 个空的Cell对象。 Then it creates a new Cell based on t1 and t2 and uses that to create a new Cell together with t3 .然后它基于t1t2创建一个新Cell ,并使用它与t3一起创建一个新Cell The issue here is that the first Cell = t1 + t2 will be destructed directly after that operation and the final tree will hold an invalid reference.这里的问题是第一个Cell = t1 + t2将在该操作之后直接被破坏,最终树将持有无效引用。

This problem could easily be overcome by doing this:这样做可以很容易地克服这个问题:

    auto h1 = t1 + t2;
    auto h  = h1 + t3;

or using new inside the overloaded addition operator operator+ .或在重载的加法运算operator+中使用new


I would like to not use new inside the operator since cleaning them up eventually could only be achieved by using some sort of tracking system.我不想在操作员内部使用new ,因为最终清理它们只能通过使用某种跟踪系统来实现。

I was wondering if there is a nice solution to this problem.我想知道这个问题是否有一个很好的解决方案。

I am very happy for any advice or help.我很高兴得到任何建议或帮助。

We have 2021 so use C++11 std::unique_ptr and std::make_unique from C++14 .我们有 2021 所以使用 C++11 std::unique_ptrstd::make_unique来自C++14

class Cell{

private:
    using ptr = std::unique_ptr<Cell>;
    ptr A;
    ptr B;

public:
    Cell() {
        std::cout << "default constructed" << std::endl;
    }

    Cell(Cell&& A, Cell&& B) {
        this->A = std::make_unique<Cell>(std::move(A));
        this->B = std::make_unique<Cell>(std::move(B));
        std::cout << "default constructed" << std::endl;
    }

    T(Cell&& other){
        this->A = std::move(other.A);
        this->B = std::move(other.B);
        std::cout << "move constructed" << std::endl;

    }
    Cell& operator=(Cell&& other){
        this->A = std::move(other.A);
        this->B = std::move(other.B);
        std::cout << "move assigned" << std::endl;
        return *this;
    }

    Cell operator+(Cell&& other) && {
        return T{std::move(*this), std::move(other)};
    }

    ptr clone() const {
        if (this)
            return std::make_unique<Cell>(A->clone(), B->clone());
        return nullptr;
    }

    virtual ~Cell() {
        std::cout << "destructed" << std::endl;
    }
};

If you need actual copy constructors assignments then utilize clone method.如果您需要实际的复制构造函数分配,请使用clone方法。

Or you can use shared_ptr , but in this case it would be safer Cell to be not mutable.或者您可以使用shared_ptr ,但在这种情况下,不可变的Cell会更安全。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM