Вы можете объявить переменную a Triangle*
, а не Shape*
, таким образом у вас будет доступ к методам и переменным производного класса и базового класса:
int main()
{
Triangle* sh = new Triangle();
Square* sh2 = new Square();
std::cout << sh->getArea() << std::endl; //3
std::cout << sh2->getArea() << std::endl; //16
std::cout << sh->sideA << std::endl; //3
std::cout << sh2->sideA << std::endl; //4
delete sh;
}
Для использования delete sh
безопасно вы должны иметь виртуальный деструктор
class Shape
{
public:
virtual double getArea() = 0;
virtual ~Shape(){} //virtual destructor
};
Поскольку у вас уже есть абстрактный класс, почему бы не использовать его для доступа к данным в производных классах:
Вот как Я бы сделал это :
#include <iostream>
#include <memory>
class Shape
{
private:
double sideA; //shared members can be defined in base class, assuming all
//derived classes will have sideA member
protected:
Shape(double sideA) : sideA(sideA) {}//for initialization of sideA in derived classes
public:
Shape() = default;
virtual double getArea() = 0;
double getSideA() { //shared logic
return sideA;
}
virtual ~Shape(){} //virtual destructor
};
class Triangle : public Shape
{
private:
double height = 2; //specific property
public:
Triangle() : Shape(3) {} //intialize sizeA
double getHeight(){ //specific method, must instanciate Triangle to access
//for collections it's best to use interface method like getArea()
return height;
}
double getArea() override {
return 0.5 * getSideA() * height;
}
};
class Square : public Shape
{
public:
Square() : Shape(4) {} //intialize sizeA
double getArea() override {
return getSideA() * getSideA();
}
};
int main()
{
std::unique_ptr<Shape> sh(new Triangle); //smart pointer
std::unique_ptr<Shape> sh2(new Square); //smart pointer
std::cout << sh->getArea() << std::endl; //3
std::cout << sh2->getArea() << std::endl; //16
std::cout << sh->getSideA() << std::endl; //3
std::cout << sh2->getSideA() << std::endl; //4
//delete sh; //no need, smart pointer
}
Взгляните на умные указатели .