Где ошибка?

spaun13

#include <iostream>
 
 
class Shape
{
public:
    Shape(****** a = 0, ****** b = 0)
    {
        x = a;
        y = b;
    }
    virtual ****** getArea() = 0;
    ****** x;
    ****** y;
    ****** area;
};
 
class Triangle : public Shape
{
public:
    Triangle(****** xx = 0,****** yy = 0):Shape(x, y)
    {
 
    }
    ****** getArea()
    {
        area = 0.5*x*y;
        std::cout << "Area of triangle = " << std::endl; return area;
    }
};
 
class Rectangle : public Shape
{
public:
    Rectangle(****** xx = 0, ****** yy = 0):Shape(x, y)
    {
 
    }
    ****** getArea()
    {
        area = x*y;
        std::cout << "Area of rectangle = " << std::endl; return area;
    }
};
 
class Square : public Shape
{
public:
    Square(****** xx = 0, ****** yy = 0):Shape(x, y)
    {
 
    }
    ****** getArea()
    {
        area = x*y;
        std::cout << "Area of square = " << std::endl; return area;
    }
};
 
int main()
{
    Triangle n(2.0, 7.0);
    Rectangle m(9.0, 4.0);
    Square l(7.0, 8.0);
 
    Shape *first = &n;
    Shape *second = &m;
    Shape *third = &l;
 
    first->getArea();
    second->getArea();
    third->getArea();
    system("pause");
    return 0;
}
10 ответов

spaun13

Если базовый класс имеет виртуальный метод, то этот метод в производных классах также виртуальный, и нет смысла писать виртуал, хотя для удобства можно и написать.


spaun13

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


spaun13

Во первых если класс будет наследоваться поставь себе за привычку создавать виртуальный деструктор:
{
public:
    Shape(****** a = 0, ****** b = 0)
    {
        x = a;
        y = b;
    }
    virtual ~Shape() {}
    virtual ****** getArea() = 0;
    ****** x;
    ****** y;
    ****** area;
};
Во вторых он у тебя ничего не выводит из-за того что ты не указал что нужно выводить. std::cout << "Area of triangle = " << area << std::endl; return area;и то что ты возвращаешь из функции значение означает что ты можешь получить значение из вне, поместив это значение в переменную. Например:
****** area;
area = first->getArea();
std::cout << area;
area = second->getArea();
std::cout << area;
area = third->getArea();
std::cout << area;


spaun13

Triangle(****** xx = 0,****** yy = 0):Shape(x, y)
а x и у откуда берутся если Вы создаете
Triangle n(2.0, 7.0);
будет неизвестое значение


spaun13

Triangle(****** xx = 0,****** yy = 0):Shape(x, y)
Твой конструктор принимает 2 переменные ******: xx и yy, и ты пытаешся передать в конструктор родительского класса переменные x и y. Если не ошибаюсь для них сработает конструктор по-умолчанию и они будут равны 0, либо какойто мусор, который хранился до этого в этом участке памяти. Надо передавать значения так:
Triangle(****** xx = 0,****** yy = 0):Shape(xx, yy)
Конструктор это всего лишь функция(метод) который выполняеться после алокации памяти, чтоб выполнить инициализацию переменых или других обьектов. Так как триангл и другие классы наследуються от Шейпа, то это значит что у них есть свойства и переменые базового класса, т.е. есть переменные x и y, но они только поместились в памяти не инициализированы, и ты этот муссор передаешь родительському классу. Из-за этого и не понятки получаються Так же именно после двух точек ты вызываешь конструкторы для элементов класса, если же ты там ничего не написал сработает конструктор по-умолчанию. В твоем случае
    Shape(****** a = 0, ****** b = 0)
    {
        x = a;
        y = b;
    }
Сначала для х и у сработал конструктор по-умолчанию, где их значения стали нулями, а после этого в теле функций ты вызываешь оператор присваивания, где уже помещаешь нужные тебе значения. Эфективнее делать так:
    Shape(****** a = 0, ****** b = 0): x(a), y(b)
    {
  
    }
В этом случае ты сразу вызываешь для них конструктор с нужными параметрами. И не забывай про порядок, вызывай конструкторе в таком же порядке ккак и обьявлены элементы в классе. если х первый стоит то сначала для него вызываешь, или наоборот с у.


spaun13

Спасиб Щас пишет последняя фигурная скобка ее нету.......


spaun13

Рабочий код. На мой взгляд самый оптимальный вариант
#include <iostream>
 
 
class Shape
{
public:
    Shape(****** a = 0, ****** b = 0) 
    : x(a)
    , y(b)
    {}
    virtual ~Shape() {}
    virtual ****** getArea() = 0;
    ****** x;
    ****** y;
};
 
class Triangle : public Shape
{
public:
    Triangle(****** xx = 0,****** yy = 0)
    : Shape(xx, yy)
    {
 
    }
    ****** getArea()
    {
        return 0.5*x*y;
    }
};
 
class Rectangle : public Shape
{
public:
    Rectangle(****** xx = 0, ****** yy = 0)
    : Shape(xx, yy)
    {
 
    }
    ****** getArea()
    {
        return x*y;
    }
};
 
class Square : public Shape
{
public:
    Square(****** xx = 0, ****** yy = 0)
    : Shape(xx, yy)
    {
 
    }
    ****** getArea()
    {
        return x*y;
    }
};
 
int main()
{
    Triangle n(2.0, 7.0);
    Rectangle m(9.0, 4.0);
    Square l(7.0, 8.0);
 
    Shape *first = &n;
    Shape *second = &m;
    Shape *third = &l;
 
    ****** trArea, reArea, sqArea;
    trArea = first->getArea();
    reArea = second->getArea();
    sqArea = third->getArea();
 
    std::cout << "Area of triangle = " << trArea << std::endl;    
    std::cout << "Area of rectangle = " << reArea << std::endl;    
    std::cout << "Area of sqArea = " << sqArea << std::endl;    
 
    system("pause");
    return 0;
}
Или так:
#include <iostream>
 
 
class Shape
{
public:
    Shape(****** a = 0, ****** b = 0) 
    : x(a)
    , y(b)
    {}
    virtual ~Shape() {}
    ****** getArea() { return area; }
    virtual void showArea() = 0;
    ****** x;
    ****** y;
    ****** area;
};
 
class Triangle : public Shape
{
public:
    Triangle(****** xx = 0,****** yy = 0)
    : Shape(xx, yy)
    {
       area = 0.5*x*y;
    }
    void showArea()
    {
       std::cout << "Triangle area = " << area << std::endl;
    }
};
 
class Rectangle : public Shape
{
public:
    Rectangle(****** xx = 0, ****** yy = 0)
    : Shape(xx, yy)
    {
       area = x*y;
    }
    void showArea()
    {
       std::cout << "Rectangle area = " << area << std::endl;
    }
 
};
 
class Square : public Shape
{
public:
    Square(****** xx = 0, ****** yy = 0)
    : Shape(xx, yy)
    {
       area = x*y;
    }
    void showArea()
    {
       std::cout << "Square area = " << area << std::endl;
    }
};
 
int main()
{
    Triangle n(2.0, 7.0);
    Rectangle m(9.0, 4.0);
    Square l(7.0, 8.0);
 
    Shape *first = &n;
    Shape *second = &m;
    Shape *third = &l;
 
    ****** trArea, reArea, sqArea;
    trArea = first->getArea();
    reArea = second->getArea();
    sqArea = third->getArea();
 
    std::cout << "Area of triangle = " << trArea << std::endl;    
    std::cout << "Area of rectangle = " << reArea << std::endl;    
    std::cout << "Area of sqArea = " << sqArea << std::endl; 
 
    first->showArea();   
    second->showArea();   
    third->showArea();   
 
    system("pause");
    return 0;
}
Нет смысла каждый раз вычислять значения,
    ****** getArea()
    {
        area = 0.5*x*y;
        std::cout << "Area of triangle = " << std::endl; return area;
    }
если они у тебя не меняються, лучше сразу в конструкторе вычислить а потом просто возвращать значения


spaun13

Да все норм!)


spaun13

Почему метод showArea(), в производных классах не виртуальный?


spaun13

Почему метод showArea(), в производных классах не виртуальный?
а кто тебе сказал что он не виртуальный?)