Почему в C++ «виртуальный» и «= 0» оба необходимы для описания метода, является абстрактным?

Вопрос: Как поясняется на языке программирования C++: virtual void push(char c) = 0; virtual void pop() = 0; Слово virtual означает, что "может быть переопределено позже в классе, полученном из этого" Синтаксис =0 указывает, что некоторый класс, полученный из Stack, должен определить функцию. Итак, зачем нужен символ =0? Означает ли это, что производный класс должен

Вопрос:

Как поясняется на языке программирования C++:

virtual void push(char c) = 0; virtual void pop() = 0;

Слово virtual означает, что “может быть переопределено позже в классе, полученном из этого”
Синтаксис =0 указывает, что некоторый класс, полученный из Stack, должен определить функцию.

Итак, зачем нужен символ =0? Означает ли это, что производный класс должен определить эту функцию, и что, если нет =0, некоторые производные классы не вынуждены определять этот метод?

Я смущаюсь по этому поводу, мне нужна помощь.

Лучший ответ:

Твои мысли были верны.

Итак, зачем нужен символ 0? Означает ли это, что дочерний класс должен определить эту функцию, а что сказать, когда нет = 0, некоторые дочерние классы не вынуждены определять этот метод?

В основном вы можете:

  • Сделать метод не виртуальным

Это не позволяет любому классу получить класс, реализующий метод (через public или protected), чтобы изменить поведение метода.

  • Сделать метод virtual

Это позволяет (но не обеспечивает) какой-либо класс, полученный из класса, который реализует метод (через public или protected), чтобы изменить поведение метода в базовом классе. Вам даже не нужно вызывать метод исходного базового класса, поэтому при необходимости вы можете внести серьезные изменения.

  • Сделать метод pure virtual (virtual = 0)

Это гарантирует, что любой класс, полученный из класса, реализующего метод (через public или protected) для реализации какого-либо поведения/тела для этого метода. Если класс выведения не обеспечивает реализацию, то этот класс мгновенно станет абстрактным. Это позволяет опустить поведение/тело метода в базовом классе, и из-за этого ему не разрешается напрямую создавать экземпляр класса, который имеет один или несколько чистых виртуальных методов (абстрактный класс).

Ответ №1

Итак, зачем нужен символ 0?

Рассмотрим следующее:

struct foo { virtual void some() const { cout << «foo» << endl; } }; struct bar : public foo { virtual void some() const { cout << «bar << endl; } }; struct baz : public foo { }

Предположим, у вас есть указатель foo *p указывающий на какой-либо объект, и вы вызываете p->some().

  • Если p указывает на объект- bar, он будет печатать «bar».

  • Если p указывает на объект baz, он будет печатать «foo».

В некоторых случаях это может быть не то, что вы хотите. Вы можете указать, что любой производный класс должен переопределить его. Это =0.

Ответ №2

Итак, зачем нужен символ 0?

Виртуальная функция с последовательностью = 0 известна как чистая виртуальная функция (последовательность = 0 известна как pure-specifier), она делает класс абстрактным классом, который не может быть создан. Для производных классов, если они хотят создать экземпляр, они должны реализовать чистую виртуальную функцию.

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

Например,

class Stack { virtual void push(char c) = 0; }; … Stack s; // Fail, Stack is an abstract class

и если

class Stack { virtual void push(char c); }; … Stack s; // Fine, if you won’t call ‘push()’ on it. Ответ №3

Цель абстрактного класса (эти классы имеют чистый виртуальный метод, =0) – предоставить соответствующий базовый класс, из которого могут наследовать другие классы. Абстрактные классы не могут использоваться для создания объектов и служат только как интерфейс.

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

Это базовая концепция интерфейса.

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

Ответ №4

Сначала рассмотрим, в чем причина использования виртуальных методов.

1.Interface (полиморфизм).

Интерфейс в C++ – это чистый виртуальный класс, что означает, что все его методы являются чистыми виртуальными (как эти два, упомянутые выше), он имеет виртуальный деструктор и не имеет конструктора (это очевидно, t создавать свои экземпляры). Он также не должен иметь никаких данных.

Пусть определите интерфейс (чистый абстрактный класс в C++):

class Interface { public: virtual ~Interface(){} virtual void somePublicMethod() = 0; };

И определите класс, который представляет собой реализацию интерфейса:

class Implementation : public Interface { public: ~Implementation() override {} void somePublicMethod() override {} };

Если вы определяете другой чистый виртуальный метод в интерфейсе:

virtual void anotherPublicMethod() = 0;

И вы не переопределяете его в реализации, вы получите ошибку компиляции, когда вы объявите объект типа реализации, поскольку реальный объект реализации должен иметь определения (тела) для всех производных методов.

Yo также может определять поведение по умолчанию для некоторого метода интерфейса:

void Interface::somePublicMethod() { //define default behavior here }

И назовите его в производном классе:

void Implementation::somePublicMethod() { Interface::somePublicMethod(); }

Как интерфейс используется в полиморфизме, который вы прочтете в других темах.

2. “Обычное” наследование.

В “обычном” наследовании вы должны использовать виртуальные методы вместо чистых виртуальных, потому что вы хотите иметь экземпляры как базового класса, так и класса Derived. Виртуальные методы указывают только, что они могут быть переопределены в производном классе.

Вывод

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

Оцените статью
Добавить комментарий