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);
    }
}
Как это понять? Функции присваивается ноль? Или это указатель который нулём инициализирован? Но это функция, или указатель на функцию, для которой может быть выделено место. Или возвращаемый указатель на тип. Но для чего ноль? Он обязателен?

Ответ на: комментарий от ckotinko

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

Кстати, почему такую конструкцию не разрешили (начиная с С++11)?:

virtual void method() = nullptr;

ИМХО, чуть более явно описывает что здесь происходит (а именно часть «указатель в vtable»).

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

Тебе анонимус ниже все правильно написал. Унарный минус расспарсить можно без контекста дальше одного экспрешона.

То что я привел, ты не распарсишь, не таская список всех типов (на этапе парсинга, уау).

А парсеры-то, прикинь, давно все написаны.

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

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

Никаких vtable в стандарте нет, и в любом случае приведённая аллюзия слишком далека от правды, чтобы ссылаться на неё в синтаксисе.

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

в плюсах бы давно выкинули forward declaration

Если ты про синтаксис объявлений, то Страуструп в D&E писал что поначалу хотел придумать другой, но так и не придумал и забил.

Но есть маленькие шажки к нормальным объявлениям: «auto f() -> t», «using a = b».

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

Тогда не понял, чем плох «struct A»?

Это, кстати, не эквивалентные конструкции

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

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

Тем, что его нужно писать. Хотя тут спорно, конечно, что лучше. // щас бы еще не вышедшие модули вспомнить

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

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

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

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

Нет никакой неоднозначности. a и b нигде не объявлены. Парсер распарсит и выдаст ошибку.

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

Таки я не понял, в чём неэквивалентность здесь

auto f() -> t;

t f(); 
???

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

Сам с собой общаешься?

С чего ты взял? Я отвечаю какому-то Кузи, который не может однозначно распарсить а звёздочка бе.

alexku
()
Ответ на: комментарий от Kuzy
struct A {
  std::vector<int> v;

  decltype(v) f() const; // std::vector<int>::iterator
  auto f() const -> decltype(v); // std::vector<int>::const_iterator
}

Не вкурил. При чём тут итератор и почему во втором варианте он константный?

alexku
()
Ответ на: комментарий от alexku
struct a {
  ...
};
a * b;
int a;
int b;
...
a * b;

Ну давай, распарси a * b не протаскивая информацию о типах в парсер.

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

Ты не понял о чем речь. Тут говорят не про то что C невозможно распарсить - очевидно что это не так. Тут говорят что парсер C усложняется тем что к нему не должно иметь отношения (и почти во всех ЯП не имеет) - информацией о типах. Гугли lexer hack, классификацию грамматик и т. п.

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

Потому что с trailing return type, decltype работает в контексте функции, а не структуры. Как если бы ты его написал в определении функции.

Функция константная -> используется константная перегрузка begin().

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

Какой begin()? Где begin()?

struct A {
  std::vector<int> v;

  //Означает "я тебе щас целый вектор целых верну, а мемберы класса изменять не позволю.
  //Попытаешься - получишь простыню егогов."
  decltype(v) f() const; // std::vector<int>::iterator

  //Означает "я тебе щас целый вектор целых верну, а мемберы класса изменять не позволю.
  //Попытаешься - получишь простыню егогов."
  auto f() const -> decltype(v); // std::vector<int>::const_iterator
  //И где разница? И при чём тут итератор?
}

И при чём же тут итератор? И разница где?

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

И что добавление точки меняет? На что влияет? Зачем нужно? И вообще при чём тут итераторы? Я этого всего не понял.

Следующие определения между собой эквивалентны.

struct A {
  std::vector<int> v;
  //Всё это - одно и то же.
  decltype(v) f() const;
  std::vector<int> f() const;
  auto f() const -> decltype(v);
  auto f() const -> std::vector<int>;
}

Аж целых четыре способа объявить функцию, которая возвращает вектор и не позволяет внутри себя изменять переменные-члены класса!

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

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

Нет, друг дорогой, давай ты сам свои домыслы обосновывать будешь. Я не телепат, чтобы твои мысли угадывать. Давай, расскажи нам, куда там v.begin() написать надо и почему всё есть так как ты говоришь. Обоснуй.

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

Не, не, не, не годится. Не надо сливаться и переводить стрелки на стековерфлоу. Я не у него спрашивал, а у тебя. И твой код отличается от того, что приведено там. Давай, на основе своего кода объясни, что ты имел ввиду. Если ты забыл свой код, я тебе его напомню.

struct A {
  std::vector<int> v;

  decltype(v) f() const; // std::vector<int>::iterator

  auto f() const -> decltype(v); // std::vector<int>::const_iterator
}

Начинай.

И, я - не царь.

alexku
()
3 мая 2018 г.
Ответ на: комментарий от d_a

ИМХО, наговариваете вы на Страуструпа. Я C++ изучал по второму изданию, не зная язык ранее.А C узнал за неделю до этого по K&R. Мне хватило. Правда я уже в принципе был хорошо знаком с парадигмами, которые предлагают эти языки. В этом вопросе да, ни та ни другая книга не предполагает учиться по ней программировать, только лишь изучить новый язык.

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