Я пытаюсь скомпилировать следующий код:
#include "Fraction.cpp"#include "Pile.cpp"#include "Plus.cpp"#include <iostream>
using namespace std;
Nombre calcul(Element* tab [], int nbElement){
Pile<Nombre> pile = Pile<Nombre>(30);
for(int i = 0 ; i < nbElement ; i++){
if( tab[i]->getType() == "o" ){
Fraction f = (*tab[i])(pile.pop(),pile.pop());
pile.push(f);
}
else if(tab[i]->getType() == "n"){
pile.push(*(tab[i]));
}
}
return pile.pop();
}
int main(){
}
Вот необходимые классы:
Fraction.hpp:
#include <iostream>
#include "Element.cpp"using namespace std;class Fraction : public Nombre{
private:
int nume;
int deno;
static int pgcd(int x, int y);
public:
Fraction(int n, int d);
Fraction(int n);
int getNume() const;
int getDeno() const;
virtual string getType();
Fraction operator+(const Fraction &) const;
Fraction operator-(const Fraction &) const;
};
ostream &operator<<(ostream &os,const Fraction &f);
Fraction operator+(const int &n,const Fraction &f);
Pile.hpp:
template <typename T> class Pile{
private:
int size;
int top;
T* stacktab;
public:
Pile<T>();
Pile<T>(int s);
bool isEmpty();
bool isFull();
bool push(T elt);
T pop();
void afficher(ostream &flux);
};
Element.cpp:
#include <string>
using namespace std;
class Element{
public:
virtual string getType() = 0;
};class Operateur : public Element{
public:
virtual string getType() ;
};
class Nombre : public Element{
public:
virtual string getType() ;
};
string Operateur::getType() {
return "o";
}
string Nombre::getType() {
return "n";
}
Plus.cpp:
class Plus : public Operateur{
public:
Fraction operator()(Fraction f1, Fraction f2);
};
class Moins : public Operateur{
public:
Fraction operator()(Fraction f1, Fraction f2);
};
Fraction Plus::operator()(Fraction f1,Fraction f2){
return f1 + f2;
}
Fraction Moins::operator()(Fraction f1, Fraction f2){
return f1 - f2;
}
Я получаю 2 ошибки, когда я пытаюсь скомпилировать этот код:
1) error: no match for call to ‘(Element) (Nombre, Nombre)’
Fraction f = (*tab[i])(pile.pop(),pile.pop());
Здесь * tab [i] — указатель на Element, но предполагается, что экземпляр будет Plus или Moins (оба являются производными от Operateur, а Operateur — от Element). Я понимаю проблему: я реализовал operator () только в классах Plus и Moins, поэтому компилятор не может найти его в Element, но как я могу это исправить?
2) error: no matching function for call to ‘Pile<Nombre>::push(Element&)’
pile.push(*(tab[i]));
note: candidate: bool Pile<T>::push(T) [with T = Nombre]
template <typename T> bool Pile<T>::push(T elt){
^
note: no known conversion for argument 1 from ‘Element’ to ‘Nombre’
Я использую кучу, и я пытаюсь нажать () с элементом Element. Поскольку Nombre является производным от Element, я не смогу ли я использовать объект Element вместо объекта Nombre?
Я искал ответы часами, но до сих пор не понимаю. Я чувствую, что не поняла чего-то очень простого.
Вам нужно иметь virtual Fraction operator()(Fraction f1, Fraction f2);
в элементе.
Но это не сработает так просто, потому что Fraction является производной от Element, поэтому еще не была объявлена. Вы могли бы попробовать virtual Element operator()(Element e1, Element e2);
, Но вы обнаружите, что возвращение неоднородного типа из Plus и Moins будет другой проблемой.
Вы толкаете неоднородные типы на кучу. Это не сработает. Даже если фракция получена из Nombre, это не совсем Nombre, и она будет ломтиком.
Других решений пока нет …