带有指针的运算符重载

Operator overloading with pointers

本文关键字:运算符 重载 指针      更新时间:2023-10-16

大家好,有c++程序员。我遇到了一个我不能理解的问题。出于可读性的原因,我删除了以下程序,并留下了我遇到的问题。我正在尝试重载一个+和=运算符,但要使用动态创建的数组。+和=运算符方法本身就产生了正确的结果。然而,当我试图将+运算符的结果分配给*poly3时,我从编译器中得到"*poly3需要初始化"。如果我真的初始化了它,就不会有任何东西被分配给它(我指的是+的结果)。我的问题是,做这件事的正确方法是什么。我需要结果poly3是动态数组或指针,这样我就可以在后面使用它。

非常感谢您提前提供的帮助。

class Polynomial
{
    private:
        int *poly;
        int size;
    public:
        Polynomial();
        Polynomial(int);
        Polynomial(string,int);
        ~Polynomial();
        void setPoly(string);
        int *getPoly() const;
        Polynomial operator+(Polynomial&);
        void operator=(const Polynomial&);
};
Polynomial::Polynomial(string polyInput, int s) 
{
    size = s+1;
     poly = new int[size];
    //set all coef position to 0
    for(int i = 0; i < size; i++){
        *(poly + i) = 0;
    }
    setPoly(polyInput);
}
Polynomial Polynomial::operator+(Polynomial &polyRight)
{
    Polynomial *result = new Polynomial(size);
    for(int i = 0; i < size; i++)
        result->poly[i] = poly[i] + polyRight.poly[i];
    return *result;
}
void Polynomial::operator=(const Polynomial &polyRight)
{
    size = polyRight.size;
    for(int i = 0; i < size; i++){
        *(poly + i) = polyRight.poly[i];
    }
}
int main()
{
    int highestExp = 4;
    Polynomial *poly1;
    Polynomial *poly2;
    Polynomial *poly3;// = new Polynomial(highestExp); // for the result
    string input1,input2;

    ifstream inputFile("data.txt");
    getline(inputFile, input1);
    getline(inputFile, input2);
    poly1 = new Polynomial(input1,highestExp);
    poly2 = new Polynomial(input2,highestExp);
    *poly3 = *poly1 + *poly2;
    system("pause");
    return 0;
}

赋值运算符必须返回对分配给的实例的引用

Polynomial& operator=(const Polynomial&);

在实现中,您应该return *this;。您还必须确保实现对于不同大小的多项式的分配是稳健的。目前情况似乎并非如此。

然后,在main中,poly3未初始化。只需删除指针并将所有poly实例化为自动存储,即main():中的本地变量

Polynomial poly1(input1,highestExp);
Polynomial poly2(input2,highestExp);
Polynimial poly3 = poly1 + poly2;

顺便说一句,您的operator+内存泄漏。您不应该使用new int it。创建一个本地Polynomial并返回它。

此外,您没有负责释放资源的析构函数,因此Polynomial的每个实例化都会导致内存泄漏。你的班级有太多的责任:管理资源和做多项式。您应该让另一个类负责内存管理。使用std::vector<int>,或者,如果这是一个练习,编写自己的类似动态数组的类,并在Polynomial中使用它。

指针指向明确分配给它的内存位置。

Ptr* pt = new Ptr();//pt points to a valid address in memory
Ptr* pt;//pt has not yet been initialized 

即它没有指向任何有效地址。使用pt可能会导致意外行为。默认情况下,指针应该指向NULL,并且应该检查它们!NULL,然后使用。

在上述代码中多项式*poly3;没有指向任何位置,当我们指向时*pol3我们实际上是在取消引用一个从未创建过的位置。

当您执行多项式*poly3=新多项式(highestExp);时;,您将poly3指向某个有效位置,因此*pol3=*poly1+*pol2是有意义的。但是要注意,当您为poly3做一个新的操作时,您正在创建一个又一个堆存储,所以您必须确保释放堆上分配的所有内存。

一个更好的解决方案是让您的oper+返回一个有效的指针,并将其映射到poly3,如下所示:

Polynomial* Polynomial::operator+(Polynomial &polyRight)
{
  Polynomial *result = new Polynomial(size);
  for(int i = 0; i < size; i++)
    result->poly[i] = poly[i] + polyRight.poly[i];
  return result;
}

//并且在主中

poly3 = (*poly1 + *poly2);

开始于:

                                             // allow adding const
const Polynomial Polynomial::operator+(const Polynomial &polyRight) const
{
    Polynomial result(size); // don't use a pointer
    for(int i = 0; i < size; i++)
        result.poly[i] = poly[i] + polyRight.poly[i];
    return result;
}

使返回常量避免(A+B)=C; 的愚蠢

Polynomial&  Polynomial::operator=(const Polynomial &polyRight) // return a reference
{
    size = polyRight.size;
    for(int i = 0; i < size; i++){
        *(poly + i) = polyRight.poly[i];
    }
    return *this; // allow chaining
}

请注意,一旦您对此进行了修补,就需要防止operator =():中的A=A

if (this == &rhs)
{
     // do stuff
}
return *this;

这是一个相当大的清理,有一些稍微不同的功能和更好的内存管理。由于我不知道你输入文件的格式,我跳过了从文件中读取的部分,只使用了Polynomial(countOfExponents, x0, x1, x2, x3, ... , xn)形式的新构造函数

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <fstream>
#include <iostream>
#include <sstream>
#include <cstdarg>
using namespace std;

class Polynomial
{
    private:
        int *poly;
        int size;
    public:
        Polynomial() : size(0), poly(NULL) {}
        Polynomial(int size, ... );
        ~Polynomial() { delete[](poly); }
        void allocate(int size) { 
            if (NULL!=poly) {
                delete[](poly);
            }
            Polynomial::size = size; 
            poly=new int[size]; 
        }
        Polynomial operator+(const Polynomial&) const;
        Polynomial &operator=(const Polynomial&);
        int exponent(int p) const {
            return (p<size) ? poly[p] : 0;
        }
        string str() const;
};
Polynomial::Polynomial(int size, ...) : size(size) {
    va_list varargs;
    va_start(varargs, size);
    poly = new int[size];
    for (int i=0; i<size; i++) {
        poly[i] = va_arg(varargs, int);
    }
    va_end(varargs);
}
Polynomial Polynomial::operator+(const Polynomial &polyRight) const
{
    int newSize = max(size, polyRight.size);
    Polynomial result;
    result.allocate(newSize);
    for(int i = 0; i < newSize; i++)
        result.poly[i] = exponent(i) + polyRight.exponent(i);
    return result;
}
Polynomial &Polynomial::operator=(const Polynomial &polyRight)
{
    allocate(polyRight.size);
    memcpy(poly, polyRight.poly, sizeof(int) * size);
    return *this;
}
string Polynomial::str() const {
    stringstream out;
    for (int i=size-1; i>=0; i--) {
        out << poly[i];
        if (0<i) {
            out << "  ";
        }
    }
    return out.str();
}
int main()
{
    Polynomial one(3, 1, 2, 3);
    Polynomial two(3, 2, 3, 4);
    cout << one.str() << endl;
    cout << two.str() << endl;
    Polynomial three = one + two;
    cout << three.str() << endl;
    return 0;
}

注意,在处理不同大小的多项式时,我也要小心不要处理可能不存在的内存。访问指数小于n的多项式上的poly[n]会引起麻烦。相反,使用指数(n)函数,它将为所有高于多项式内指数的指数返回0。