2014-11-26 3 views
0

У меня есть класс, определенный как это:Getting класс ребенок определяется как родительский класс для вывода функции ребенка

#include <vector> 
#include <string> 
#include <iostream> 
#include <sstream> 

using namespace std; 

class Shape { 
protected: 
    float width, height; 
public: 
    virtual ~Shape(){} 

    void set_data (float a, float b){ 
     width = a; 
     height = b; 
    } 

    virtual string getType() { 
     return "Shapes"; 
    } 
}; 

class Polygon: public Shape { 
public: 
    virtual ~Polygon(){}; 

    virtual string getType() { 
     return "Polygon"; 
    } 
}; 

class Triangle: public Polygon { 
    public: 
     virtual ~Triangle(){}; 

    virtual string getType() { 
     return "Triangle"; 
    } 
}; 

И я хочу, чтобы получить программу, которая использует этот класс

int main() { 
    Shape poly = Polygon(); 
    Shape tri = Triangle(); 
    std::cout << poly.getType() << std::endl; 
    std::cout << tri.getType() << std::endl; 
    return 0; 
} 

Есть ли способ получить poly.getType() для распечатки Polygon, например? Сейчас он печатает Shapes. Я знаю, что если бы я сделал

Polygon poly = Polygon() 

, что делает трюк, но я хочу, чтобы хранить poly как Shape объекта, построить его с помощью Polygon конструктора, и убедитесь, что

poly.getType() 

возвращается Polygon, не Shapes ,

ответ

1

Полиморфизм работает только с неосновными типами; то есть со ссылками и указателями. И поскольку ссылки должны быть немедленно привязаны, здесь они не очень полезны.

Лучше всего использовать std::unique_ptr<Shape> poly(new Polygon()); и вызов с помощью

poly->getType();

Я использую std::unique_ptr так мне не нужно называть delete явно. std::shared_ptr тоже будет работать, но обратитесь к документации, чтобы использовать наиболее подходящий для вашего случая использования.

Кстати, вам не нужно повторять virtual при переопределении функции в дочерних классах. Вам нужно только отметить функцию virtual в базовом классе.

+0

Да, это сработало! Спасибо всем, кто ответил! – ndb

+0

Убедитесь, что вы прочитали документы на 'unique_ptr', хотя, если вы решите использовать его. – Bathsheba

1

Ваш код страдает object slicing. Использование:

int main() { 
    std::unique_ptr<Shape> poly = new Polygon(); 
    std::unique_ptr<Shape> tri = new Triangle(); 
    std::cout << poly->getType() << std::endl; 
    std::cout << tri->getType() << std::endl; 
    return 0; 
} 
+0

Спасибо, это именно то, что я хочу. Будет принимать после того, как переполнение стека позволит мне – ndb

+0

Cute (+1), но если 'getType()' должен был выбросить исключение, вы будете утечки памяти. – Bathsheba

+0

Больше не нужно .... – Bathsheba

0

Сделать переменным тип строки. Установите его в каждый подклассу. Имейте функцию getType в форме, которая возвращает ее.

0

Этот ответ выше в основном был прав: «Мне нужно использовать указатели» - это ключ.

Это решило мою проблему:

int main() 
{ 
    Polygon poly = Polygon(); 
    Shape* testing = &poly; 
    std::cout << testing->getType() << std::endl; 
    return 0; 
} 

Я принимаю ваш ответ примерно через час времени, потому что переполнение стека заставляет меня ждать некоторое время, прежде чем принять. Спасибо