C++ 如何使用运算符+;过载功能?

C++ 如何使用运算符+;过载功能?,c++,C++,我创建了一个类,它可以添加两个多项式系数,这两个系数只是 动态数组索引位置。我的主要问题是重载+函数返回值。一旦我加上 同一类的两个对象,如果我试图返回一个对象,Visal Studio将给我一个错误 变量,但如果我将构造函数返回到一个对象,那么代码工作正常,并且没有 错误。我不知道为什么会出现这个错误,就像我以前在动态数组上的作业一样,我 返回对象变量没有任何问题?我不知道返回的规则是什么 在这种情况下,运算符+重载功能的值是多少?谢谢 #include <iostream> #i

我创建了一个类,它可以添加两个多项式系数,这两个系数只是 动态数组索引位置。我的主要问题是重载+函数返回值。一旦我加上 同一类的两个对象,如果我试图返回一个对象,Visal Studio将给我一个错误 变量,但如果我将构造函数返回到一个对象,那么代码工作正常,并且没有 错误。我不知道为什么会出现这个错误,就像我以前在动态数组上的作业一样,我 返回对象变量没有任何问题?我不知道返回的规则是什么 在这种情况下,运算符+重载功能的值是多少?谢谢

#include <iostream>
#include <vector>
using namespace std;


class polynomial
{
public:
  polynomial();
  polynomial(vector<double> vec);
  polynomial(const polynomial& obj);
  void get();
  polynomial& operator=(const polynomial& rightSide);
  friend const polynomial operator +(const polynomial& x, const polynomial& y);
  //The function in question
  ~polynomial() { delete[] p; };
private:
  double *p;
  int expSize;
};


int main() 
{
  vector<double> x(3);
  vector<double>y(3);
  x = { 2,3,4 };
  y = { 4,3,2 };

  polynomial X(x);              //<-- Both objects are constructed with vectors
  polynomial Y(y);

  polynomial obj;
  obj = X + Y;                 //<-- Adding dynamic arrays, and saving the values in obj.

  obj.get();
  cout << endl;

  system("pause");
  return 0;
}

polynomial::polynomial()
{
  expSize = 3;
  p = new double[expSize];

  for (int c = 0; c < expSize; c++)
      p[c] = 0;
}

polynomial::polynomial(vector<double>vec)
{   
  expSize = vec.size();

  p = new double[expSize];
  for (int c = 0; c < expSize; c++)                 
      p[c] = 0;                                     
  for (int c = 0; c < expSize; c++)                 
      p[c] = vec[c];                                

}

polynomial::polynomial(const polynomial& obj)
{
  p = new double[expSize];
  for (int c = 0; c < expSize; c++)
      p[c] = obj.p[c];
}

polynomial& polynomial::operator=(const polynomial& rightSide)
{
  if (this == &rightSide)
      return *this;
  else
  {
      expSize = rightSide.expSize;
      delete[] p;
      p = new double[expSize];

      for (int c = 0; c < expSize; c++)
          p[c] = rightSide.p[c];

      return *this;
  }
}

const polynomial operator +(const polynomial& x, const polynomial& y)
{
  polynomial obj;

  if (x.expSize > y.expSize)                //<-- obj.expSize private member variable will 
      obj.expSize = x.expSize;              //    inherit the larger dynamic array index size
  else if(x.expSize <= y.expSize)           //    of the two parameter objects.
      obj.expSize = y.expSize;

  for (int c = 0; c < obj.expSize; c++) {
      obj.p[c] = x.p[c] + y.p[c];
  }
  vector<double>vec(obj.expSize);            //<-- Vector will inherit the new index size too.
  for (int c = 0; c < obj.expSize; c++) {
      vec[c] = obj.p[c];                     //<-- Vector takes joined values of two objects
  }

  //return polynomial(vec);                 //<-- Returning a constructor with vector works fine
  return obj;                              //<-- abort() has been called error
}

void polynomial::get()
{
  for (int c = 0; c < expSize; c++)
      cout << p[c] << endl;
}
#包括
#包括
使用名称空间std;
类多项式
{
公众:
多项式();
多项式(向量向量向量);
多项式(常数多项式&obj);
void get();
多项式和运算符=(常数多项式和右侧);
friend常数多项式算子+(常数多项式&x,常数多项式&y);
//所讨论的功能
~polymonal(){delete[]p;};
私人:
双*p;
int-expSize;
};
int main()
{
向量x(3);
向量(3);
x={2,3,4};
y={4,3,2};

多项式X(X);//典型的解决方案是将public
操作符+=
实现为 返回对
*此
的非常量引用,然后在类外使用它返回
运算符+

inline polynomial operator+(polynomial x, const polynomial& y) {
    x += y;
    return x;
}
或与一行相同:

inline polynomial operator+(polynomial x, const polynomial& y) {
    return x += y;
}
在这个过程中,编译器将尽量避免大量的复制或移动

请注意,也可以使用参数
x
作为常量的参考来编写:

inline polynomial operator+(const polynomial& x, const polynomial& y) {
    polynomial ret = x;
    ret += y;
    return ret;
}

在这里,我们总是将
x
复制到
ret
。另一个变量允许调用方进入参数
x
,因此有更多的优化使用机会。

典型的解决方案是将public
操作符+=
作为 返回对
*此
的非常量引用,然后在类外使用它返回
运算符+

inline polynomial operator+(polynomial x, const polynomial& y) {
    x += y;
    return x;
}
或与一行相同:

inline polynomial operator+(polynomial x, const polynomial& y) {
    return x += y;
}
在这个过程中,编译器将尽量避免大量的复制或移动

请注意,也可以使用参数
x
作为常量的参考来编写:

inline polynomial operator+(const polynomial& x, const polynomial& y) {
    polynomial ret = x;
    ret += y;
    return ret;
}

在这里,我们总是将
x
复制到
ret
。另一个变量让调用方进入参数
x
,因此有更多的最佳使用机会。

我只想提出一些建议。
多项式的复制ctor有一个bug。它应该是:

polynomial::polynomial(const polynomial &obj)
{
  expSize = obj.expSize;
  p = new double[expSize];
  for (int c = 0; c < expSize; c++) p[c] = obj.p[c];
}
但如果你必须以朋友的身份实施它:

多项式运算符+(常数多项式&x,常数多项式&y)
{
向量向量机;
对于(int c=0;((c

最后,我认为您应该为您的类实现一个移动向量和一个移动赋值操作符

我只想提出一些建议。
多项式
复制向量有一个bug。它应该是:

polynomial::polynomial(const polynomial &obj)
{
  expSize = obj.expSize;
  p = new double[expSize];
  for (int c = 0; c < expSize; c++) p[c] = obj.p[c];
}
但如果你必须以朋友的身份实施它:

多项式运算符+(常数多项式&x,常数多项式&y)
{
向量向量机;
对于(int c=0;((c

最后,我认为您应该为您的类实现一个移动构造函数和一个移动赋值操作符。

要快速回答您的问题:从任何函数返回类实例的正确方法是返回该类构造函数支持的任何对象

注:多项式最好用

以下代码段中定义的代码是对
多项式类的改进。它更有效,它有一个移动向量,还引入了空数组的概念。请仔细研究

#ifndef POLYNOMIAL_H
#define POLYNOMIAL_H

#include <iostream>
#include <initializer_list>

class polynomial
{
private:
  int size;      // size must always be > 0
  double *array; // null value implies, array = [0];

public:
  /*
  1) default ctor
  2) ctor providing support for initializer list : polynomial P = {1, 2, 3};
  3) ctor providing support for STL containers like std::vector<> etc;
  4) copy ctor
  5) move ctor
  */
  polynomial(void);                                                                // (1)
  polynomial(const std::initializer_list<double>&);                                // (2)
  template<template<typename...> class T, typename _Tp> polynomial(const T<_Tp>&); // (3)
  polynomial(const polynomial&);                                                   // (4)
  polynomial(polynomial&&);                                                        // (5)
 ~polynomial(void);

  polynomial& operator=(const polynomial&);
  polynomial& operator=(polynomial&&);
  polynomial& operator=(const std::initializer_list<double>&);
  template<template<typename...> class T, typename _Tp> polynomial& operator=(const T<_Tp>&);

  int order(void) const;
  void clear(void);

  void set(const int &index, const double &value);
  double get(const int &index) const;
  double operator[](const int &index) const;

  polynomial operator+(const polynomial&) const;
  polynomial operator-(const polynomial&) const;

  friend std::basic_ostream<char>& operator<<(std::basic_ostream<char> &O, const polynomial&);
};

#endif  /* POLYNOMIAL_H */
输出为:


多项式.cpp的实现

#包括“polynomy.h”
#包括
#包括
#包括
多项式::多项式(void):大小(1),数组(nullptr)
{
//
}
多项式::多项式(const std::初始值设定项\u list和args):多项式()
{
如果(args.size()>0){size=args.size();array=new double[size];std::copy(args.begin(),args.end(),array);}
}
模板多项式::多项式(常数T和数据):多项式()
{
如果(data.size()>0){size=data.size();数组=new double[size];std::copy(data.begin(),data.end(),array);}
}
多项式::多项式(常数多项式&P):多项式()
{
如果((P.array!=nullptr)&&(P.size>0)){size=P.size;array=new double[size];std::copy(&P.array[0],&P.array[size],array);}
}
多项式::多项式(多项式&&P):多项式()
{
std::swap(大小,P.size);std::swap(数组,P.array);
}
多项式::~多项式(空)
{
if(array){delete[]数组;array=nullptr;}size=0;
}
整数多项式::阶(空)常数
{
返回(大小-1);
}
void多项式::清除(void)
{
if(array){delete[]数组;array=nullptr;}size=1;
}
多项式和多项式::运算符=(常数多项式和P)
{
返回((this!=&P)?运算符=(多项式(P)):(*this));
}
多项式和多项式::运算符=(多项式和P)
{
if(this!=&P){clear();std::swap(size,P.size);std::swap(array,P.array);}返回(*this);
}
多项式和多项式::运算符=(常量std::初始值设定项\u列表和参数)
{
返回运算符=(多项式(args));
}
模板多项式和多项式::运算符=(常量T和数据)
{
返回运算符=(多项式(数据));
}
空多项式::集合(常数int&i,常数double&d)
{
如果((大小<1)| |(i<0)
#include "polynomial.h"
using namespace std;

int main(int argc, char** argv)
{
  polynomial A = {1, 2, 3};
  polynomial B;
  cout << "A: " << A.order() << endl;
  cout << "B: " << B.order() << endl;
  cout << (A + B) << endl;
  return 0;
}
A: 2
B: 0
3(x^2) + 2x + 1
#include "polynomial.h"
#include <sstream>
#include <algorithm>
#include <list>

polynomial::polynomial(void) : size(1), array(nullptr)
{
  //
}

polynomial::polynomial(const std::initializer_list<double> &args) : polynomial()
{
  if (args.size() > 0) { size = args.size(); array = new double[size]; std::copy(args.begin(), args.end(), array); }
}

template<template<typename...> class T, typename _Tp> polynomial::polynomial(const T<_Tp> &data) : polynomial()
{
  if (data.size() > 0) { size = data.size(); array = new double[size]; std::copy(data.begin(), data.end(), array); }
}

polynomial::polynomial(const polynomial &P) : polynomial()
{
    if ((P.array != nullptr) && (P.size > 0)) { size = P.size; array = new double[size]; std::copy(&P.array[0], &P.array[size], array); }
}

polynomial::polynomial(polynomial &&P) : polynomial()
{
  std::swap(size, P.size); std::swap(array, P.array);
}

polynomial::~polynomial(void)
{
  if (array) { delete[] array; array = nullptr; } size = 0;
}

int polynomial::order(void) const
{
  return (size - 1);
}

void polynomial::clear(void)
{
  if (array) { delete[] array; array = nullptr; } size = 1;
}

polynomial& polynomial::operator=(const polynomial &P)
{
  return ((this != &P) ? operator=(polynomial(P)) : (*this));
}

polynomial& polynomial::operator=(polynomial &&P)
{
  if (this != &P) { clear(); std::swap(size, P.size); std::swap(array, P.array); } return (*this);
}

polynomial& polynomial::operator=(const std::initializer_list<double> &args)
{
  return operator=(polynomial(args));
}

template<template<typename...> class T, typename _Tp> polynomial& polynomial::operator=(const T<_Tp> &data)
{
  return operator=(polynomial(data));
}

void polynomial::set(const int &i, const double &d)
{
  if ((size < 1) || (i < 0) || (i >= size)) throw "index out of bounds!";
  if (array == nullptr) { array = new double[size]; } array[i] = d;
}

double polynomial::get(const int &i) const
{
  if ((size < 1) || (i < 0) || (i >= size)) throw "index out of bounds!";
  return ((array == nullptr) ? 0 : array[i]);
}

double polynomial::operator[](const int &i) const
{
  return get(i);
}

polynomial polynomial::operator+(const polynomial &B) const
{
  std::list<double> data;
  auto &A = (*this);

  for (int i = 0; ((i < A.size) || (i < B.size)); ++i)
  {
    data.push_back(0);
    if (i < A.size) data.back() += A.get(i);
    if (i < B.size) data.back() += B.get(i);
  }

  return data;
}

polynomial polynomial::operator-(const polynomial &B) const
{
  std::list<double> data;
  auto &A = (*this);

  for (int i = 0; ((i < A.size) || (i < B.size)); ++i)
  {
    data.push_back(0);
    if (i < A.size) data.back() += A.get(i);
    if (i < B.size) data.back() -= B.get(i);
  }

  return data;
}

std::basic_ostream<char>& operator<<(std::basic_ostream<char> &O, const polynomial &P)
{
  if ((P.array != nullptr) && (P.size > 0))
  {
    std::basic_stringstream<char> sout;

    sout.precision(O.precision());

    sout.flags(sout.flags() | (O.flags() & std::ios::floatfield));

    for (int i = (P.size - 1), j = 0; (i >= 0); --i, ++j)
    {
      if (j == 0) sout << P.array[i];
      else sout << ((P.array[i] < 0) ? " - " : " + ") << std::abs(P.array[i]);
      if (i >= 2) sout << "(x^" << i << ')';
      if (i == 1) sout << 'x';
    }

    O << sout.str();
  }
  else
  {
    O << 0;
  }

  return O;
}