Пример указателя на объект класса в Stack Overflow

В следующем коде в функции main форма объявлена ​​как указатель на объект класса Shape, но адрес объекта класса Rectangle, а именно rec, сохранен в следующей строке. Может кто-нибудь сказать мне, где я ошибаюсь в моем понимании.

class Shape {
protected:
int width, height;
public:
Shape( int a=0, int b=0)
{
width = a;
height = b;
}
int area()
{
cout << "Parent class area :" <<endl;
return 0;
}
};

class Rectangle: public Shape{
public:
Rectangle( int a=0, int b=0)
{
Shape(a, b);
}
int area ()
{

return (width * height);
}
};
class Triangle: public Shape{
public:
Triangle( int a=0, int b=0)
{
Shape(a, b);
}
int area ()
{

return (width * height / 2);
}
};int main( )
{
Shape *shape;//pointer to Shape class
Rectangle rec(10,7);
Triangle  tri(10,5);shape = &rec;//address of Rectangle class object saved
shape->area();

shape = &tri;
shape->area();

return 0;
}

-1

Решение

Shape должен объявить area как virtual получить полиморфное поведение.

virtual int area()
{
...
}
3

Другие решения

В вашем коде есть несколько ошибок, и в результате код не имеет смысла.

Рассмотрим для примера конструктор

  Triangle( int a=0, int b=0)
{
Shape(a, b);
}

Сначала будет вызван конструктор по умолчанию Shape, потому что вы не указали вызов конструктора Shape в списке инициализации ctor. Таким образом, ширина и высота будут установлены в ноль конструктором по умолчанию.
Внутри тела конструктора Triangle вы просто создаете временный объект типа Shape, который никогда не будет использоваться.

Это может выглядеть как унылый путь

  Triangle( int a=0, int b=0) : Shape( a, b ) {}

или даже как

  explicit Triangle( int a=0, int b=0) : Shape( a, b ) {}

если вы знаете, что означает явное.

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

class Shape {
protected:
int width, height;
public:
Shape( int a=0, int b=0) : width( a ), height( b ) {}

virtual ~Shape() {}

virtual int area() const = 0;
};

int Shape::area() const
{
cout << "Parent class area :" <<endl;
return 0;
}

И uodate производные классы в соответствии с этими изменениями.

1

Rectangle происходит от Shapeсмотрите строчку

class Rectangle: public Shape

Это называется наследованием или отношением «is-a»: Rectangle это Shape, Следовательно, Shape* может указывать на прямоугольник. Больше информации, например, можно найти в Указатель базового класса против унаследованного указателя класса? или большинство учебников по C ++, охватывающих наследование.

Как отмечает ответ Родди, вы должны заявить area в Shape как virtualиначе звоню shape->area() всегда буду звонить Shape«s area метод вместо переопределенного метода, предоставляемого Rectangle, поскольку area за Shape на самом деле не имеет смысла, вы могли бы даже рассмотреть вопрос об объявлении его как чисто виртуальный:

virtual int area() = 0;
0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector