我使用`std :: map。
制作了一个基本程序来操作多项式这是源代码
polynome.hpp
#ifndef POLYNOME_HPP
#define POLYNOME_HPP
using namespace std;
template<typename T>
string to_string( const T & Value )
{
//Utiliser un flux de sortie pour créer la chaîne
ostringstream oss;
//Ecrire la valeur dans le flux
oss << Value;
//Renvoyer une string
return oss.str();
}
template <typename T>
class Polynome
{
public:
//Constructeurs et destructeur
Polynome();
Polynome(const Polynome &);
Polynome(T (tab[]), unsigned int);
Polynome(map<unsigned int, T>&);
~Polynome(){}
//Méthodes d'accès
unsigned int GetOrder() const {return ItsOrder;}
map<unsigned int, T> GetPoly() const {return ItsPolynome;}
void SetOrder(unsigned int order) { ItsOrder=order;}
void SetPoly(map<unsigned int, T> poly){ItsPolynome=poly;}
//Surcharge d'opérateur
T & operator[](unsigned int);
T operator[](unsigned int) const;
Polynome operator+(const Polynome &);
Polynome operator-(const Polynome &);
Polynome operator*(const Polynome &);
Polynome& operator=(const Polynome &);
template <typename U>
friend ostream& operator<<(ostream&, Polynome<U>&);
//Autres méthodes
void Deriv();
T Eval(const Polynome &, T);
private:
//Données membres
map<unsigned int,T> ItsPolynome;
unsigned int ItsOrder;
};
//Constructeur par défaut
template <typename T>
Polynome<T>::Polynome(): ItsOrder(0)
{
map<unsigned int, T> m;
m[0]=0;
ItsPolynome=m;;
}
//Constructeur de copie
template <typename T>
Polynome<T>::Polynome(const Polynome<T> & rhs)
{
map<unsigned int, T> m;
m[0]=0;
ItsPolynome=m;
map<unsigned int, T> a=rhs.GetPoly();
for(typename map<unsigned int, T>::const_iterator ii=a.begin();ii!=a.end(); ++ii)
{
ItsPolynome[ii->first] = ii->second;
}
ItsOrder=rhs.GetOrder();
}
//Constructeur à partir d'un tableau contenant les coefficients
template <typename T>
Polynome<T>::Polynome(T (tab)[],unsigned int size)
{
map<unsigned int, T> m;
m[0]=0;
ItsOrder=0;
ItsPolynome=m;
for(unsigned int i=0;i<size;i++)
{
ItsPolynome[i]=tab[i];
}
ItsOrder=size-1;
}
//Constructeur qui prend une map(tableau associatif) en paramètre
template <typename T>
Polynome<T>::Polynome(map<unsigned int, T> & a)
{
ItsPolynome=a;
unsigned int b=0;
for(typename map<unsigned int, T>::const_iterator ii=a.begin();ii!=a.end(); ++ii)
{
if((ii->first)>b)
{
b=ii->first;
}
}
ItsOrder=b;
}
//Opérateur d'indexation non constant
template <typename T>
T & Polynome<T>::operator[](unsigned int n)
{
if(ItsPolynome.count(n))
{
return ItsPolynome[n];
}
else
{
return 0;
}
}
//Opérateur d'indexation constant
template <typename T>
T Polynome<T>::operator[](unsigned int n) const
{
if(ItsPolynome.count(n))
{
return ItsPolynome[n];
}
else
{
return 0;
}
}
//Surcharge de l'opérateur +
template <typename T>
Polynome<T> Polynome<T>::operator+(const Polynome<T> & rhs)
{
map<unsigned int, T> polyrhs=rhs.GetPoly();
/*On définit l'ordre du nouveau polynôme obtenu. */
if(ItsOrder<rhs.GetOrder())
{
ItsOrder=rhs.GetOrder();
}
/* On additionne enfin les deux polynômes pour obtenir une map pour le polynôme obtenu suite à l'addition. */
for(typename map<unsigned int, T>::const_iterator ii=polyrhs.begin();ii!=polyrhs.end(); ++ii)
{
ItsPolynome[ii->first]+=polyrhs[ii->first];
}
}
//Surcharge de l'opérateur - (analogue à la surcharge de l'opérateur +)
template <typename T>
Polynome<T> Polynome<T>::operator-(const Polynome<T> & rhs)
{
map<unsigned int, T> polyrhs=rhs.GetPoly();
/*On définit l'ordre du nouveau polynôme obtenu. */
if(ItsOrder<rhs.GetOrder())
{
ItsOrder=rhs.GetOrder();
}
/* On additionne enfin les deux polynômes pour obtenir une map pour le polynôme obtenu suite à l'addition. */
for(typename map<unsigned int, T>::const_iterator ii=polyrhs.begin();ii!=polyrhs.end(); ++ii)
{
ItsPolynome[ii->first]-=polyrhs[ii->first];
}
}
//Surcharge de l'opérateur *
template <typename T>
Polynome<T> Polynome<T>::operator*(const Polynome<T> & rhs)
{
map<unsigned int, T> polyrhs=rhs.GetPoly();
/*On définit l'ordre du nouveau polynôme obtenu. */
ItsOrder=ItsOrder+rhs.GetOrder();
/* On additionne enfin les deux polynômes pour obtenir une map pour le polynôme obtenu suite à l'addition. */
for(int i=0;i<=ItsOrder;i++)
{
for(int j=0; j<=i;j++)
{
ItsPolynome[i]+=ItsPolynome[j]*polyrhs[i-j];
}
}
}
//Surcharge de l'opérateur de flux
template <typename T>
ostream& operator<<(ostream& stream, Polynome<T>& p)
{
string a="", b="", c="";
map<unsigned int, T> poly=p.GetPoly();
for(typename map<unsigned int, T>::const_iterator ii=poly.begin();ii!=poly.end(); ++ii)
{
b=to_string(ii->second);
c=to_string(ii->first);
a+="+"+b+"x^"+c;
}
stream<<a;
return stream;
}
//Surcharge de l'opérateur d'affectation
template <typename T>
Polynome<T>& Polynome<T>::operator=(const Polynome<T> & rhs)
{
if(this==&rhs)
{
return *this;
}
ItsOrder=rhs.GetOrder();
ItsPolynome=rhs.GetPoly();
return *this;
}
//Méthode permettant de dériver le polynôme
template <typename T>
void Polynome<T>::Deriv()
{
//On définit l'ordre du polynôme dérivé
if(ItsOrder==0)
{
ItsOrder=0;
}
else
{
ItsOrder--;
}
//On définit les coefficients du polynôme dérivé (On prend chaque a*x^n un a un, et la dérivation le transforme en a*n*x^(n-1) )
for(typename map<unsigned int, T>::const_iterator ii=ItsPolynome.begin();ii!=ItsPolynome.end(); ++ii)
{
if((ii->first)!=0)
{
ItsPolynome[ii->first-1]=(ii->second)*(ii->first);
ItsPolynome[ii->first]=0;
}
}
}
//Méthode permettant d'évaluer le polynôme en un point x
template <typename T>
T Polynome<T>::Eval(const Polynome<T> & p, T x)
{
T a=0;
map<unsigned int, T> poly=p.GetPoly();
for(typename map<unsigned int, T>::const_iterator ii=poly.begin();ii!=poly.end(); ++ii)
{
a+=(ii->second)*(pow(x,ii->first));
}
return a;
}
#endif
的main.cpp
#include <iostream>
#include <string>
#include <cstring>
#include <sstream>
#include <cmath>
#include <map>
#include "polynome.hpp"
using namespace std;
int main()
{
double tab[3]={1.0,1.0,1.0};
map<unsigned int, double> m;
m[0]=1;
m[1]=1;
m[2]=1;
Polynome<double> p(m);
Polynome<double> q(tab,3);
Polynome<double> r;
cout<<p<<endl;
cout<<q<<endl;
r=p+q;
cout<<r<<endl;
return 0;
}
/*Le programme a été écrit sur gedit, et compilé sous gcc avec le warning Weffc++ */
此程序编译,但有以下警告
In file included from main.cpp:7:0:
polynome.hpp: In instantiation of ‘Polynome<T>::Polynome(std::map<unsigned int, T>&) [with T = double]’:
main.cpp:18:22: required from here
polynome.hpp:94:1: warning: ‘Polynome<double>::ItsPolynome’ should be initialized in the member initialization list [-Weffc++]
Polynome<T>::Polynome(map<unsigned int, T> & a)
^
polynome.hpp:94:1: warning: ‘Polynome<double>::ItsOrder’ should be initialized in the member initialization list [-Weffc++]
polynome.hpp: In instantiation of ‘Polynome<T>::Polynome(T*, unsigned int) [with T = double]’:
main.cpp:19:26: required from here
polynome.hpp:79:1: warning: ‘Polynome<double>::ItsPolynome’ should be initialized in the member initialization list [-Weffc++]
Polynome<T>::Polynome(T (tab)[],unsigned int size)
^
polynome.hpp:79:1: warning: ‘Polynome<double>::ItsOrder’ should be initialized in the member initialization list [-Weffc++]
polynome.hpp: In instantiation of ‘Polynome<T>::Polynome() [with T = double]’:
main.cpp:20:19: required from here
polynome.hpp:54:1: warning: ‘Polynome<double>::ItsPolynome’ should be initialized in the member initialization list [-Weffc++]
Polynome<T>::Polynome(): ItsOrder(0)
^
,结果是:
“+ 1X ^ 0 + 1×^ 1 + 1×2 ^
+ 1X ^ 0 + 1×^ 1 + 1×2 ^
Erreur de segmentation(核心倾销) “
所以,我想了解,在我的程序中,在添加方法中有什么问题,因为我认为这个问题就在这里。
非常感谢您阅读此内容。 ;)
PS:对不起我的英文,我是法国人。 并对不起代码的介绍。 如果你愿意,我会引用评论,如果你愿意,我可以这样做。 ;): - )
答案 0 :(得分:2)
我立即看到的明显错误是您没有从需要返回值的函数返回值。
例如,查看您的operator+
功能:
template <typename T>
Polynome<T> Polynome<T>::operator+(const Polynome<T> & rhs)
{
map<unsigned int, T> polyrhs = rhs.GetPoly();
if (ItsOrder<rhs.GetOrder())
{
ItsOrder = rhs.GetOrder();
}
for (typename map<unsigned int, T>::const_iterator ii = polyrhs.begin(); ii != polyrhs.end(); ++ii)
{
ItsPolynome[ii->first] += polyrhs[ii->first];
}
// <-- Where is the return value?
}
您不会返回值。不返回值是未定义的行为。该函数应该返回一个Polymer<T>
对象,但你没有这样做。
您对其他重载运算符犯了同样的错误,因此您还需要更改它们。某些运算符(例如+
)应该const
到他们执行的对象上。您需要按值返回精心设计的对象;不要修改现有对象:
//Surcharge de l'opérateur +
template <typename T>
Polynome<T> Polynome<T>::operator+(const Polynome<T> & rhs) const
{
Polynome<T> res = *this; // make copy of this object
res.ItsOrder = std::max(res.ItsOrder, rhs.ItsOrder);
for(auto const& term : rhs.ItsPolynome)
res.ItsPolynome[term.first] += term.second;
return res; // return crafted object by-value.
}
答案 1 :(得分:1)
您需要返回operator+()
的值。这同样适用于operator-()
和operator*()
。
出了什么问题?
您已定义所有这些运算符以覆盖当前对象,因此p+q
会修改p
而不是保持p
和q
不变并产生结果。由于您没有返回值,因此完全未定义赋值运算符可以复制的内容。因此,段错误。
还有什么问题?
如果您返回*this
,代码会编译但不会按预期工作!对于简单表达式r=p+q
,它将使用p
的内容覆盖p+q
,并将p
的新值复制到r
。 r
符合您的预期,但您希望p
更改吗?您的代码根本无法完成更复杂的操作。假设你写了一个像r = (p+q)*(p-q)
这样的表达式;您的代码会产生未定义的行为,具体取决于编译器评估表达式的顺序!
解决问题的建议
查看有关运营商实施的 this guideline article 。
与此同时,这里有一个适用的改编版本:
template <typename T>
Polynome<T> Polynome<T>::operator+(const Polynome<T> & rhs)
{
Polynome<T> t=*this ; // temporary polynom to return
if (t.ItsOrder<rhs.GetOrder())
t.ItsOrder = rhs.GetOrder(); // take the max
for (auto ii = rhs.ItsPolynome.begin(); ii != rhs.ItsPolynome.end(); ++ii)
t.ItsPolynome[ii->first] += ii->second;
return t ;
}
答案 2 :(得分:0)
问题在于你的operator +函数 - 你说它返回Polynome<T>
但是没有return语句。
在for循环之后添加:return *this
,它应该可以正常工作。