LINUX.ORG.RU

как понять virtual Fish* Clone() const = 0;

 


0

3

Вот в книге написано.

class Fish
{
  public:
    virtual Fish* Clone () const = 0;
};

class Tuna:public Fish
{
  public:
    Tuna * Clone() const
    {
      return new Tuna(*this);
    }
}
Как это понять? Функции присваивается ноль? Или это указатель который нулём инициализирован? Но это функция, или указатель на функцию, для которой может быть выделено место. Или возвращаемый указатель на тип. Но для чего ноль? Он обязателен?

Основы C++, Вы обязатольно должны реализовать эту функцию если наследуту от этого класса.

anonymous
()
Ответ на: комментарий от anonymous

Вы обязатольно должны реализовать эту функцию если наследуту от этого класса.

Не обязательно. Класс наследник тоже может быть абстрактным.

Ivan_qrt ★★★★★
()
Ответ на: комментарий от u0atgKIRznY5

Нет, ты их вообще не можешь инициализировать, ничем. Класс с такой функцией — абстрактный, и ты не можешь создать экземпляр этого класса. Это форма записи такая. Иди, короче, читай Страуструпа.

fluorite ★★★★★
()
Последнее исправление: fluorite (всего исправлений: 2)
Ответ на: комментарий от fluorite

Да тут в книжке написано. Я знаю что его наследовать надо, и что деструктор виртуальный нужно, чтобы класс из выделенной памяти выполнял деструкторы всех классов. И что есть таблица виртуальных функций, которая указывает на фукнции классов. Но вот этот вид, я незнаю как описание на него найти. Как можно функции присвоить ноль?

u0atgKIRznY5
() автор топика
Ответ на: комментарий от u0atgKIRznY5

Как ты вообще объявлению функции что-то присвоишь? Это не присваивание, это такой синтаксис, смирись.

fluorite ★★★★★
()
Последнее исправление: fluorite (всего исправлений: 1)
Ответ на: комментарий от u0atgKIRznY5

Да тут в книжке написано.

В какой книжке? У Страуструпа это описано. Вообщем возьми нормальную книжку.

Как можно функции присвоить ноль?

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

Begemoth ★★★★★
()
Ответ на: комментарий от u0atgKIRznY5

Нет здесь присваивания, просто у C-семейства очень ублюдочный синтаксис.

thunar ★★★★★
()
Ответ на: комментарий от Begemoth

Ну не ключевое же слово ради этого в язык добавлять

А почему бы и нет? А ещё можно было @ а не * для указателей заюзать. Глядишь, и код бы был бы больше похож не фигурное месиво на читабельный текст.

thunar ★★★★★
()

man prototype pattern

Как это понять? Функции присваивается ноль?

а, понятно. nevermind.

vvviperrr ★★★★★
()
Последнее исправление: vvviperrr (всего исправлений: 1)
Ответ на: комментарий от u0atgKIRznY5

Язык программирования C++ любого издания

XMs ★★★★★
()

Что же вы все от чтения Страуструпа отбрыкиваетесь, «изучая» С++.

В каждой своей книге объясняет. В D&E так и причины указал, почему именно явный «псевдоинициализатор», почему такой синтаксис, и почему посчитал это лучше, чем весь класс помечать как абстрактный.

anonymous
()

Каждый раз проигрываю с этого места в синтаксисе крестов.

Deleted
()
Ответ на: комментарий от anonymous

Слово самому:

Странный синтаксис =0 был выбран вместо очевидной альтернативы ввести ключевое слово pure или abstract только потому, что тогда я не видел возможности добавить новое ключевое слово. Если бы я предложил pure, то версия 2.0 вышла бы без абстрактных классов.

Чтобы не рисковать сроками выпуска версии и не навлекать на себя упреков по поводу нового ключевого слова, я воспользовался традиционным для С и C++ соглашением о том, что 0 означает «отсутствует».

Синтаксис = 0 не противоречит моим взглядам на тело функции как на инициализатор функции, а также представлениям (упрощенным, но обычно соответствующим реальности) о том, что множество виртуальных функций реализовано в виде вектора указателей на функции (см. раздел 3.5.1). На самом деле, реализация синтаксиса =0 путем помещения 0 в vtbl - не лучший способ. Я помещал в vtbl указатель на функцию pure_virtual_called ; затем эту функцию можно было определить так, чтобы она выводила подходящее сообщение об ошибке во время выполнения.

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

(c)

anonymous
()
Ответ на: комментарий от thunar

А почему бы и нет?

Текст, к сожалению, не передаёт интонации, предполагалась легкая ирония.

А ещё можно было @ а не * для указателей заюзать.

Было даже боле масштабное предложение

Begemoth ★★★★★
()
Ответ на: комментарий от u0atgKIRznY5

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

evilface ★★
()

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

Если по факту, то = 0 означает, что в данном классе нет реализации метода Clone. Поэтому нельзя создать объект класса Fish. Но можно создать потомка класса Fish в котором будет реализована функция Clone. И вот уже для класса потомка можно создать экземпляр класса.

P.S. Для лучшего понимания зачем это нужно - читай GoF, там примерчики есть простые.

Norgat ★★★★★
()
Ответ на: комментарий от Begemoth

Ну не ключевое же слово ради этого в язык добавлять.

А вот в объектном паскале не поленились и добавили слово abstract. И это гораздо понятнее, чем брейнфаковщина с =0.

hobbit ★★★★★
()
Последнее исправление: hobbit (всего исправлений: 1)
Ответ на: комментарий от anonymous

Что же вы все от чтения Страуструпа отбрыкиваетесь, «изучая» С++.

Книжка то хорошая, просто написана на манер reference manual (а по российски --- справочник), и неявно предполагает, что читатель в общем C++ уже знает (читай --- успешно стреляет себе в ноги).

d_a ★★★★★
()
Ответ на: комментарий от hobbit

Ну, типа, вперёд к

public static class Foo {
  public static void Bar() { }
}
или к
function Next (k: in Number) return Number is
begin
  return k + 1;
end Next;

Begemoth ★★★★★
()
Последнее исправление: Begemoth (всего исправлений: 2)
Ответ на: комментарий от Softwayer

Пользуясь случаем, замечу, что все, кто утверждает, что у pure virtual функции не может быть реализации в базовом классе, ошибаются

Полюбому. Более того, если деструктору дать «=0», то он обязан быть определен все равно.

xoomer
()
Ответ на: комментарий от Softwayer

Пользуясь случаем

Вау :-) Вот это ты открыл истину :-) Никто не знал ведь :-) Это в совеременных ВУЗах таким знаниям обучают? :-) Или ты тут просто Скота Мейерса цитируешь на вольных началах? :-) Лол :-) Хахаха :-)

anonymous
()
Ответ на: комментарий от Softwayer

Блин. То есть мне опять рушить мой мир?
Нет, гибкость, это круто. Но, думаю, новичкам некисло взрывает мозг.

Kroz ★★★★★
()

Как это понять?

Это понимать так, что в классе Fish объявляется «чисто виртуальная функция», без имплементации. Поэтому экземпляр класса Fish ты создать не можешь. Класс, который содержит хотябы одну такую функцию (и экземпляр которого ты не моешь создать), называется абстрактным. Зачем это делается? Чтобы рассказать, что все наследники класса Fish должны иметь эту функцию, и да, там она должна иметь имплементацию (ну, если только ты не хочешь создать еще один абстрактный класс).

Функции присваивается ноль?

Эта штука существует только для виртуальных функций-членов класса (что вполне логично). Виртуальная функция - это на самом деле указатель на функцию. То есть считай, что это ты указателю присваиваешь ноль aka NULL (Если не писать «=0» после виртуальной функции - обычная виртуальная функция, - то указателю присваивается адрес функции)

Kroz ★★★★★
()
Последнее исправление: Kroz (всего исправлений: 2)

Функции присваивается ноль?

А если мы пишем Tuna() = delete, то присваивается delete, да?

RazrFalcon ★★★★★
()

Это называется чистая виртуальная функция (или pure virtual function). Означает то, что производный класс должен её имплементировать. Обычно используются для определения интерфейсов

invy ★★★★★
()
Ответ на: комментарий от thunar

А почему бы и нет? А ещё можно было @ а не * для указателей заюзать. Глядишь, и код бы был бы больше похож не фигурное месиво на читабельный текст.

Да-да, и $ для переменных. И получился бы perl. Очень читабельно.

slovazap ★★★★★
()
Ответ на: комментарий от anonymous

Найс в глаза долбишься, смайлодаун. Вот тебе несколько цитат из треда выше:

чисто виртуальных функций (тех у которых нет реализации)

функция не реализована, = 0

= 0 означает, что в данном классе нет реализации

и даже ниже одна:

«чисто виртуальная функция», без имплементации

Если ты почему-то решил, что я тут ломающие новости специально для тебя пощу, то ты заблуждаешься.

Softwayer ★★
()

virtual X =0 говорит о том, что эта функция объявлена, под указатель на нее заложено место в vtable, но туда записан указатель на функцию __cxa_что-то-там-упасть-с-ошибкой.

ckotinko ☆☆☆
()

это очередные ляпы дворников из IT.

anonymous
()

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

u0atgKIRznY5
() автор топика
Ответ на: комментарий от u0atgKIRznY5

сама функция ( её тело ) для базового класса описываться не будет

значение адреса этой функции в таблице виртуальных функций следует оставить нулевым

Вранье по обоим пунктам. Что за мусор ты читаешь? В треде уже всё разъяснили.

anonymous
()
Ответ на: комментарий от u0atgKIRznY5

Это просто идиотский синтаксис хреного спроектированного языка. Никакой связи с присвоением там нет (ну, ее конечно можно придумать, но зачем).

Расслабься и встречай следующий WAT.

Kuzy ★★★
()
Ответ на: комментарий от slovazap
a * b;

А теперь расскажи, это а умножить на b, или указатель b. А лучше напиши парсер, который это спарсит нормально.

Kuzy ★★★
()
Ответ на: комментарий от Kuzy

Неоднозначности и другие есть. Жечь - так весь C.

anonymous
()
Ответ на: комментарий от Kuzy

А теперь расскажи, это а умножить на b, или указатель b. А лучше напиши парсер, который это спарсит нормально.

Знаешь почему ты дурачок? Не потому что ты понятия не имеешь как пишутся парсеры и работают грамматики. Это ты просто необразованный. И не потому что при этом считаешь допустимым высказывать какое-то мнение. Это ты просто молодой. А потому что у тебя не работает ассоциативное мышление и ты когда писал этот бред не вспомнил про минус, который тоже может быть унарным. Так вот я тебя прошу, умоляю просто, предложи заменить на что-нибудь унарный минус. А парсеры-то, прикинь, давно все написаны.

slovazap ★★★★★
()
Ответ на: комментарий от slovazap

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

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.