Я создаю абстрактный класс геометрии, который имеет дочерние классы. Тем не менее, я хочу, чтобы класс RightCircularCone
также имел свои собственные переменные, которые определяют его вершинные координаты, так что абстрактный класс не является ненужным большим по размеру памяти для объектов типа Sphere
, которым не требуется хранить переменные вершины. Однако я не могу получить доступ к функциям и переменным RightCircularCone
, когда я загружаю их из контейнера, который использует интеллектуальные указатели, поскольку он продолжает определяться как его родительский класс Shape
. Кто-нибудь может понять, что происходит? Ценить это!Абстрактные классы наследования и контейнеры интеллектуальных указателей
/* shapes.hpp */
class Shape{
public:
unsigned int color;
float radius;
float x,y,z;
public:
void SetSpatial(float radius, float x, float y, float z);
unsigned int GetColor(void);
void SetColor(unsigned int color);
virtual bool PointInside(const std::array<double,3> &point)=0;
};
class RightCircularCone : public Shape{
private:
float Ax,Ay,Az;
public:
bool PointInside(const std::array<double,3> &point);
void SetApex(float x, float y, float z);
void PrintApex();
};
class Sphere : public Shape{
public:
bool PointInside(const std::array<double,3> &point);
};
Классы, определенные выше, используются в другом файле .cpp, на котором определены методы класса:
#include "../../include/part.hpp" /* includes shapes.hpp in turn */
void Part::ReadPartFile(std::string partfile){
try{
std::ifstream dataFile;
dataFile.open(partfile);
//do checks, error badbits etc...
std::string word;
unsigned int counter=0;
while(!dataFile.eof()){
dataFile >> word;
if(word == "sphere"){
auto newSphere = std::make_shared<Sphere>();
// load variables into objects from file by checking each word by using setColor and setSpatial
shapeList[counter++] = newSphere;
} else if(word == "rccone"){
auto newRccone = std::make_shared<RightCircularCone>();
// load variables into objects from file by checking each word by using setColor and setSpatial and setApex
shapeList[counter++] = newRccone;
}
}
dataFile.close();
} catch(std::ifstream::failure e) {
//do exception handling here if necessary
}
Теперь, когда я использую итератор по карте std::map<unsigned int, std::shared_ptr<Shape> > shapeList;
, как определено в part.cpp
смогу никогда не обращайтесь к методам дочерних классов Sphere
и RightCircularCone
, так как карта возвращает тип Shape
, хотя я использовал умную указатель !!! Кто-нибудь знает, почему и потенциальное решение (или более простой способ настроить классы)? Спасибо!
// EDIT:
Это ошибка, я получаю:
error: no member named 'PrintApex' in 'Shape'
iterator->second->PrintApex();
Снова распространенная ошибка, отсутствие проверки извлечения потока: 'dataFile >> word;' –
Умный указатель не волшебная палочка. Почему вы ожидаете, что это сделает волшебный материал для вас? –
Ну, умные указатели в контейнере делают именно это. По крайней мере, они должны! Обычно, когда вы создаете контейнер типа родительского класса, вы можете хранить в нем тип дочернего класса, чтобы при извлечении его из контейнера вы могли использовать методы/vars этого дочернего класса, правильно? –