复制操作员无法正常工作

时间:2018-04-23 17:09:07

标签: c++ oop operator-overloading

你好我正在研究一个多语言课程。我遇到了copy(=)运算符重载的问题。让我举几个例子。

让我说我有:

  

P = 2x ^ 6 + 4x ^ 5 + 2x ^ 3 + 3x ^ 2 + 2x + 1

如果我做P = P我得到:

  

P 4x ^ 6 + 8x ^ 5 + 4x ^ 3 + 6x ^ 2 + 4x + 2

我也得到P = Q * P的东西。我不认为我的方法有任何问题,也许还有其他问题。

#include <iostream>
#include <cmath>

using namespace std;

class Polynomial {
protected:
    class Term {
    public:
        int exponent;
        int coefficient;
        Term *next;

        Term(int exp, int coeff, Term *n) {
            exponent = exp;
            coefficient = coeff;
            next = n;
        }
        ~Term(){
            delete next;
        }

        friend class Polynomial;

        friend ostream;
    };

public:
    Polynomial() {
        root = NULL;
    }

    Polynomial(const Polynomial &p) {
        Term *target = p.root;
        root = NULL;
        while (target != NULL) {
            this->addTerm(target->exponent, target->coefficient);
            target = target->next;
        }
    }

    ~Polynomial() {
        delete root;
    }

    Polynomial & operator = (const Polynomial &p){
        Term *target = p.root;
        while (target!=NULL){
            this->addTerm(target->exponent , target->coefficient);
            target = target->next;
        }
        return *this;
    }

    void addTerm(int expon, int coeff) {

        Term *prev = root;
        Term *target = root;

        if (root == NULL) {
            Term *p = new Term(expon, coeff, target);
            //Term *p = &tmp;
            root = p;
            return;
        }

        while (target != NULL && target->exponent > expon) {
            prev = target;
            target = target->next;
        }

        if (target && target->exponent == expon) {
            target->coefficient += coeff;
            if (target->coefficient == 0) {
                prev->next = target->next;
            }
            return;
        }

        if (target == root) {
            Term *p = new Term(expon, coeff, target);
            root = p;   //Set p as root
        } else {

            Term *p = new Term(expon, coeff, target);
            prev->next = p;


        }


    }

    double evaluate(double x) {
        Term *target = root;
        double sum=0;
        while (target != NULL) {
            sum += target->coefficient * pow(x, target->exponent);
            target = target->next;
        }
        return sum;
    }

    friend Polynomial operator+(const Polynomial &p, const Polynomial &q) {
        Polynomial tmp;
        Term *target = p.root;

        while (target != NULL) {
            tmp.addTerm(target->exponent, target->coefficient);
            target = target->next;

        }
        target = q.root;
        while (target != NULL) {
            tmp.addTerm(target->exponent, target->coefficient);
            target = target->next;
        }
        return tmp;

    }

    friend Polynomial operator * (const Polynomial &p, const Polynomial &q) {
        Polynomial tmp;
        Term *target_1 = p.root;
        Term *target_2 = q.root;
        while (target_1 != NULL) {
            while (target_2 != NULL) {

                tmp.addTerm(target_1->exponent + target_2->exponent, target_1->coefficient * target_2->coefficient);

                target_2 = target_2->next;
            }
            target_2 = q.root;
            target_1 = target_1->next;
        }
        return tmp;
    }


    friend ostream &operator << (ostream &out, const Polynomial &p) {
        Term *target = p.root;
        if (target!=NULL && target->coefficient < 0) cout<<"- ";

        while (target != NULL) {
            if (target->exponent){
                if (abs(target->coefficient) != 1) out << abs(target->coefficient);
            }
            else {
                out << abs(target->coefficient);
            }
            out << (target->exponent ? (target->exponent != 1 ? "x^" : "x") : "");
            if (target->exponent) {
                if (target->exponent != 1) out << target->exponent;
            }
            target = target->next;
            if (target!= NULL) {
                if (target->coefficient > 0){
                    out<<" + ";
                }
                else{
                    out <<" - ";
                }
            }


        }


        return out;
    }

private:
    Term *root;
};

#ifndef CONTEST
int main(){

    Polynomial P;
    P.addTerm(6,2);
    P.addTerm(5,4);
    P.addTerm(3,2);
    P.addTerm(2,2);
    P.addTerm(1,2);
    P.addTerm(2,1);
    P.addTerm(0,1);

    cout<<P<<endl;

    cout<<P.evaluate(0)<<endl;
   // Polynomial Q = P;

    //Polynomial S = Q*P;
    P = P;

    //cout<<S<<endl;
    cout<<P<<endl;
}

#endif

1 个答案:

答案 0 :(得分:1)

您的assert!(mine_count > 0); assert!(mine_count < 9); let mine_char = (mine_count + b'0') as char; s.insert(0, mine_char); println!("{}", s); 不正确:分配应替换当前多项式中的术语,而不是添加到它们中。您需要先清除分配给的对象:

SELECT A AS A_STANDS_ALONE,* 
FROM Table
ORDER BY A

这样做需要防止自我分配。因此,请使用以下命令启动赋值运算符:

operator=

然后清除delete root; root = nullptr; ,然后像您一样复制if (this == &p) return *this;

另一种解决方案是重用已经为复制构造函数完成的工作,并使用copy-and-swap idiom作为赋值运算符。这需要:

  1. 为您的班级定义交换功能:

    *this
  2. 更改p以按值获取其参数,并在其中交换:

    friend void swap(Polynomial &lhs, Polynomial &rhs)
    {
      std::swap(lhs.root, rhs.root);
    }
    
  3. 这样,对象operator=将初始化由复制构造函数创建,然后只与被分配的多项式交换(沿途传递其值),最后在Polynomial& operator=(Polynomial p) { swap(*this, p); return *this; } 结束时销毁,方便地处理清理指定多项式的旧值。

相关问题