2011-01-06 5 views
0

У меня есть эта программа в C++.полиморфизм подтипов в C++

ref2.h:

#ifndef REF2_H 
#define REF2_H 
#include <iostream> 
using std::cout; 
using std::endl; 

int add_int_int(int a, int b) {return (a+b);} 

class IntClass; 

class Number { 
    public: 

     //return a Number object that's the results of x+this, when x is IntClass 
     virtual Number& addInt(IntClass& x) = 0; 

     //Print the number stored in the object 
     virtual void print_number() = 0; 
    } 

class IntClass : public Number { 

    private: 
     int my_number; 

    public: 
     //Constructor 
     IntClass(int n):my_number(n) {} 

     //returns the number stored in the object 
     int get_number() {return my_number;} 

     //print the number stored in the object 
     void print_number() {cout << my_number << endl;} 

     Number& addInt(IntClass& x); 
    } 

Number& IntClass::addInt(IntClass& x) 
{ 
    int n = add_int_int(my_number, x.get_number()); 
    IntClass elem = IntClass(n); 
    IntClass &ref = elem; 
    return ref;  
} 

#endif 

test.cpp

#include "ref2.h" 
#include <iostream> 
using std::cout; 
using std::endl; 


int main() {  
    cout << "Testing subtyping polymorphism:" << endl; 
    IntClass ia(1); 
    IntClass ib(2); 
    Number& num = ia.addInt(ib);  num.print_number(); //should be: 3 
} 

я не нахожу свою ошибку. Если кто-нибудь может мне помочь?

+0

Урок на сегодня: включите свои предупреждения! :) – Kos

+2

Какие ошибки? – Falmarri

+1

Вы должны опубликовать свои ошибки компилятора или выходные данные программы и ожидаемый результат, если вы считаете, что что-то не так, а не только код. – mgiuca

ответ

1

Вы возвращает ссылку на локальный объект, который выходит за рамки, когда addInt() возвращается:

IntClass elem = IntClass(n); 
IntClass &ref = elem; 
return ref;  
3

Вы возвращает ссылку на локальную переменную в addInt(). Не делай этого. Компилятор должен был предупредить вас об этом.

+1

+1 для точной формулировки «Не делай этого». –

+0

Я думаю, что он представил местную ссылку, чтобы победить (правильное) предупреждение компилятора. –

+0

@Ben: Он точно выглядит. И он тоже укусил его в задницу! ;) – Macke

1

Концепция возврата ссылки на номер (в данном случае) является ошибочной. Подумайте о ссылке, как указатель. Функция IntClass :: addInt выделяет новый объект IntClass в стеке, а затем возвращает ссылку на него.

Когда функция возвращается, память для IntClass освобождается, поэтому ссылка указывает на мусор.

Вы должны вернуть указатель на Number (Number *), и вам нужно будет использовать new IntClass, чтобы создать его. Затем вам также нужно будет позвонить delete, когда вы закончите использовать его.