Как создать массив абстрактного класса с
Перейти к содержимому

Как создать массив абстрактного класса с

  • автор:

как создать массив абстрактного класса

Есть класс мишень и его наследник (тип мишени). Как можно создать массив таких мишеней, с разными параметрами?

class Target < protected: double _width; double _height; double _distance; int _materialShine; public: Target(double w, double h, double d, int m) : _width(w), _height(h), _distance(d), _materialShine(m) < >virtual double Visibility() = 0; >; class RectangleTarget : public Target < public: RectangleTarget(double w, double h, double d, int m) : Target(w, h, d, m) < >double Visibility() < double visible = (_width * _height + _distance) / 100 * (1.0 + _materialShine / 100); std::cout >; int main() < srand(time(NULL)); setlocale(LC_ALL, ""); int size = 10; Target** target = new Target * [size]; //target[0] = new RectangleTarget(fRand(40,90), fRand(40, 90), fRand(70, 190), iRand(0, 1)); //target[0]->Visibility(); > 

Отслеживать
задан 15 ноя 2022 в 11:56
Тимофей Рудковский Тимофей Рудковский
19 7 7 бронзовых знаков
Не понимаю вопрос — вы же это уже сделали? Надеюсь, fRand и iRand у вас определены?
15 ноя 2022 в 12:02

да, fRand и iRand определены. Проблема в том, что здесь указывается только для одной мишени параметры, а если, к примеру, их будет больше

15 ноя 2022 в 12:09
функцией double(rand()) / RAND_MAX . В чём проблема? цилк for — учили?
15 ноя 2022 в 12:12
for(int i = 0; i < size; ++i) target[i] = new RectangleTarget(. 15 ноя 2022 в 12:41

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

15 ноя 2022 в 12:42

0

Сортировка: Сброс на вариант по умолчанию

Знаете кого-то, кто может ответить? Поделитесь ссылкой на этот вопрос по почте, через Твиттер или Facebook.

  • c++
  • ооп
  • полиморфизм
  • virtual
    Важное на Мете
Похожие

Подписаться на ленту

Лента вопроса

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

Дизайн сайта / логотип © 2024 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2024.4.30.8420

Как создать массив абстрактного класса с

Иногда возникает необходимость определить класс, который не предполагает создания конкретных объектов. Например, класс фигуры. В реальности есть конкретные фигуры: квадрат, прямоугольник, треугольник, круг и так далее. Однако абстрактной фигуры самой по себе не существует. В то же время может потребоваться определить для всех фигур какой-то общий класс, который будет содержать общую для всех функциональность. И для описания подобных сущностей используются абстрактные классы.

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

Что такое чистые виртуальные функции (pure virtual functions)? Это функции, которые не имеют определения. Цель подобных функций — просто определить функционал без реализации, а реализацию определят производные классы. Чтобы определить виртуальную функцию как чистую, ее объявление завершается значением «=0». Например, определим абстрактный класс, который представляет геометрическую фигуру:

class Shape < public: virtual double getSquare() const = 0; // площадь фигуры virtual double getPerimeter() const = 0; // периметр фигуры >;

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

При этом мы не можем создать объект абстрактного класса:

Shape shape<>;

Для применения абстрактного класса определим следующую программу:

#include class Shape < public: virtual double getSquare() const = 0; // площадь фигуры virtual double getPerimeter() const = 0; // периметр фигуры >; class Rectangle : public Shape // класс прямоугольника < public: Rectangle(double w, double h) : width(w), height(h) < >double getSquare() const override < return width * height; >double getPerimeter() const override < return width * 2 + height * 2; >private: double width; // ширина double height; // высота >; class Circle : public Shape // круг < public: Circle(double r) : radius(r) < >double getSquare() const override < return radius * radius * 3.14; >double getPerimeter() const override < return 2 * 3.14 * radius; >private: double radius; // радиус круга >; int main() < Rectangle rect; Circle circle; std::cout

Здесь определены два класса-наследника от абстрактного класса Shape — Rectangle (прямоугольник) и Circle (круг). При создании классов-наследников все они должны либо определить для чистых виртуальных функций конкретную реализацию, либо повторить объявление чистой виртуальной функции. Во втором случае производные классы также будут абстрактными.

В данном же случае и Circle, и Rectangle являются конкретными классами и реализуют все виртуальные функции.

Консольный вывод программы:

Rectangle square: 1500 Rectangle perimeter: 160 Circle square: 2826 Circle perimeter: 188.4

Стоит отметить, что абстрактный класс может определять и обычные функции и переменные, может иметь несколько конструкторов, но при этом нельзя создавать объекты этого абстрактного класса. Например:

#include class Shape < public: Shape(int x, int y): x, y <> virtual double getSquare() const = 0; // площадь фигуры virtual double getPerimeter() const = 0; // периметр фигуры void printCoords() const < std::cout private: int x; int y; >; class Rectangle : public Shape // класс прямоугольника < public: Rectangle(int x, int y, double w, double h) : Shape, width(w), height(h) < >double getSquare() const override < return width * height; >double getPerimeter() const override < return width * 2 + height * 2; >private: double width; // ширина double height; // высота >; class Circle : public Shape // круг < public: Circle(int x, int y, double r) : Shape, radius(r) < >double getSquare() const override < return radius * radius * 3.14; >double getPerimeter() const override < return 2 * 3.14 * radius; >private: double radius; // радиус круга >; int main() < Rectangle rect; rect.printCoords(); // X: 0 Y: 0 Circle circle; circle.printCoords(); // X: 10 Y: 20 >

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

Абстрактные классы (C++)

Абстрактные классы используются в качестве обобщенных концепций, на основе которых можно создавать более конкретные производные классы. Невозможно создать объект абстрактного типа класса. Однако можно использовать указатели и ссылки на абстрактные типы классов.

Вы создаете абстрактный класс, объявляя по крайней мере одну чистую виртуальную функцию-член. Это виртуальная функция, объявленная с помощью синтаксиса чистого описателя ( = 0 ). Классы, производные от абстрактного класса, должны реализовывать чисто виртуальную функцию; в противном случае они также будут абстрактными.

Рассмотрим пример, представленный в функциях Virtual. Класс Account создан для того, чтобы предоставлять общие функции, но объекты типа Account имеют слишком общий характер для практического применения. Это означает Account , что это хороший кандидат для абстрактного класса:

// deriv_AbstractClasses.cpp // compile with: /LD class Account < public: Account( double d ); // Constructor. virtual double GetBalance(); // Obtain balance. virtual void PrintBalance() = 0; // Pure virtual function. private: double _balance; >; 

Единственное различие между этим и предыдущим объявлениями состоит в том, что функция PrintBalance объявлена со спецификатором чисто виртуальной функции pure ( = 0 ).

Ограничения на использование абстрактных классов

Абстрактные классы нельзя использовать для:

  • переменных и данных членов;
  • типов аргументов;
  • типов возвращаемых функциями значений;
  • типов явных преобразований.

Если конструктор абстрактного класса вызывает чистую виртуальную функцию напрямую или косвенно, результат не определен. Однако конструкторы и деструкторы абстрактных классов могут вызывать другие функции-члены.

Определенные чистые виртуальные функции

Чистые виртуальные функции в абстрактных классах можно определить или реализовать. Такие функции можно вызывать только с помощью полного синтаксиса:

Определенные чистые виртуальные функции полезны при разработке иерархий классов, базовые классы которых включают чистые виртуальные деструкторы. Это связано с тем, что деструкторы базового класса всегда вызываются во время уничтожения объектов. Рассмотрим следующий пример:

// deriv_RestrictionsOnUsingAbstractClasses.cpp // Declare an abstract base class with a pure virtual destructor. // It's the simplest possible abstract class. class base < public: base() <>// To define the virtual destructor outside the class: virtual ~base() = 0; // Microsoft-specific extension to define it inline: // virtual ~base() = 0 <>; >; base::~base() <> // required if not using Microsoft extension class derived : public base < public: derived() <>~derived() <> >; int main() < derived aDerived; // destructor called when it goes out of scope >

В примере показано, как расширение компилятора Майкрософт позволяет добавлять встроенное определение в чистую виртуальную ~base() . Его можно также определить за пределами класса с помощью base::~base() <> .

Когда объект aDerived выходит из область, вызывается деструктор класса derived . Компилятор создает код для неявного вызова деструктора класса base после derived деструктора. Пустая реализация для чистой виртуальной функции ~base гарантирует, что для функции существует хотя бы какая-то реализация. Без него компоновщик создает неразрешенную ошибку внешнего символа для неявного вызова.

В предыдущем примере чистая виртуальная функция base::~base вызывается неявно из derived::~derived . Кроме того, можно явно вызывать чистые виртуальные функции с помощью полного имени функции-члена. Такие функции должны иметь реализацию, или вызов приводит к ошибке во время связи.

Статический метод абстрактного класса, С++

Есть вот такое условие задачи: 1 Создать массив из шести объектов (по два каждого производного класса). 2 Вывести объекты на консоль через Show(). 3 Отсортировать объекты по убыванию. 4 Вывести объекты на консоль через Show(). Есть абстрактный базовый класс, к примеру, class A. От него наследуются два класса, пусть это будет class B & class C. При выполнении условия 1(создать массив из 6 объектов) я использую std::vector вот таким образом: vectorA> arr ; Далее через функцию push.pack() добавляю в него нужное количество объектов. И вот есть массив из 6 объектов. У каждого из производных классов есть свой метод Show(), который они переопределяют своей реализацией. НО, метод это не статический, а должен быть таковым (т.к. есть условие, что метод Show() нужно сделать статическим). В чем, собственно, вопрос: как мне в этой ситуации сделать метод Show() статическим? Я, честно говоря, сталкивался с работой только со статическими переменными, но не функциями. Еще есть условие, что метод Show() должен вызываться в цикле по созданному массиву. P.S. Понимаю, что такое статическая функция и т.д. Но не могу написать реализацию для этого случая.

Отслеживать

задан 12 авг 2019 в 12:14

373 1 1 серебряный знак 12 12 бронзовых знаков

если коротко — вопрос как создать статический метод? Если да, то ideone.com/dtCpxC например.

12 авг 2019 в 12:26

@pavel, я понимаю как сделать метод статическим, не понимаю как это сделать для моего случая. Тут мне нужно будет потом вызвать этот метод в цикле по созданному массиву,а что передавать в качестве аргументов в статическую функцию тогда? или она должна быть без аргументов? или она должна быть только у базового класса и не переопределяться в производных? я вот просто не знаю про это. + ко всему массив указателей на объекты.

12 авг 2019 в 12:30

статическую функцию нельзя переопределить в производном классе.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *