2016-05-26 3 views
-1

У меня возникла странная проблема. У меня есть стек литералов, который содержит целые числа, парный, Rationnals и т.д. Я определил оператор +, чтобы быть в состоянии сделать Double + Integer, Integer + Integer и т.д. Но когда я делаю:оператор + не распознает типы

Litteral& pop1 = stack.top(); 
stack.pop(); 
Litteral& pop2 = stack.top(); 
stack.pop(); 
Litteral& toAdd = (*pop1.clone() + *pop2.clone()); 

I получить:

не подходит для 'оператора +' (типы операндов 'Litteral' и 'Litteral') Litteral & toAdd = (* pop1.clone() + * pop2.clone());

Он не распознает типы, даже с помощью clone(). И мой оператор + является виртуальным. Вот как я определил оператор +:

class Integer; 

class Litteral { 
public: 
    virtual QString toString() const = 0; 
    virtual int getValue() const = 0; 
    virtual Litteral * clone() const = 0; 
    virtual Litteral& operator+(const Integer& l) = 0; 
}; 
class Integer: public Litteral { 
    friend class LitteralManager; 
    int value; 
public: 
    ... 
    virtual Integer& operator+(const Integer& e); 
    Integer* clone() const; 
}; 

Вот клон(), потому что я использую фабричную модель:

Integer* Integer::clone() const { 
    return new Integer(*this); 
} 

Кто-нибудь есть ключ? Спасибо за помощь.

+0

Ничего себе. У вас так много ошибок в коде. Я предлагаю начинать с нуля, может быть, с чем-то более простым. – juanchopanza

+0

У вас есть 'operator +', который принимает 'Litteral' и' Integer'. Нет никого, кто берет «Litteral» с обеих сторон. –

+0

Кроме того, ваша программа (после ее компиляции) будет демонстрировать неопределенное поведение. Вы берете ссылку на элемент 'top()', а затем немедленно уничтожаете этот элемент с помощью 'pop()', а затем переходите к использованию ссылки теперь. –

ответ

4

Есть много вещей неправильно с этой линией:

Litteral& toAdd = (*pop1.clone() + *pop2.clone()); 
  • Вы сразу утечкой памяти. clone() выделяет память, вы не держите указатель нигде, так что вы никогда не сможете сделать это delete.
  • operator+ должен создать новый объект, у вас есть ссылка, возвращающая ссылку - но к чему это будет возвращать ссылку? Это говорит о том, что это изменении левого аргумента, который был бы очень удивительно, если пользователям a + b модифицирована a ...
  • Вашего operator+ определяются взять правый аргумент Integer const&. Но *pop2.clone() - это Litteral. Нет стандартного преобразования базового класса в производный класс (в конце концов, это может быть не целочисленный литерал, правда?). Вот почему нет operator+. Вам нужно будет изменить подпись вашей функции. Это буквальный (ха!) Ответ на ваш вопрос.
  • Слово literal имеет только один t.

Кроме того, это плохо:

Litteral& pop1 = stack.top(); 
stack.pop(); 

Вы держите повисшего ссылку - буквальный, который был на вершине стека разрушается pop(). Любое последующее использование pop1 будет неопределенным поведением.

+0

Да, я теряю память. Не видел, спасибо. operator + возвращает ссылку, потому что вызывает фабрику, которая создает новый объект, и возвращает ссылку. Кроме того, я использую clone(), чтобы вернуть Integer. Да Integer - это Litteral, но тип объекта, возвращаемого с помощью clone(), является Integer. Так почему же это Litteral? И да, есть два т, потому что код, который я пишу, написан на французском языке. Я перевел Entier в Integer, но я не сделал этого для Litteral, извините. – Chuck

+0

Что касается стека, я не использую stl-стек, а личный, содержащий указатели, а не объекты (они хранятся в виде фабрики). Когда я pop(), я не удаляю объект, я просто удаляю его из стека. – Chuck

+1

@Chuck Кажется, что вся ваша конструкция основана на утечке памяти. Может быть, использовать язык со встроенной сборкой мусора? – juanchopanza

Смежные вопросы