Как я могу использовать ковариантные типы возврата с интеллектуальными указателями?

Исключение нулевого указателя генерируется, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:

  1. Вызов метода экземпляра объекта null.
  2. Доступ или изменение поля объекта null.
  3. Принимая длину null, как если бы это был массив.
  4. Доступ или изменение слотов null, как если бы это был массив.
  5. Бросок null как будто это было значение Throwable.

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

Ссылка: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html

63
задан Flow 31 July 2017 в 17:14
поделиться

4 ответа

Во-первых, это действительно, как это работает в C++: тип возврата виртуальной функции в производном классе должен совпасть с в базовом классе. Существует специальное исключение, что функция, которая возвращает ссылку/указатель на некоторый класс X, может быть переопределена функцией, которая возвращает ссылку/указатель на класс, который происходит от X, но поскольку Вы отмечаете, что это не допускает умный указатели (такой как shared_ptr), только для простых указателей.

, Если Ваш интерфейс RetInterface будет достаточно всесторонним, то Вы не должны будете знать фактический возвращенный тип в коде вызова. В целом это не имеет смысла так или иначе: причина get_r virtual, функция во-первых состоит в том, потому что Вы будете называть его через указатель или ссылку на базовый класс AInterface, в этом случае Вы не можете знать то, что вводит производный класс, возвратился бы. При вызове этого с фактическим A1 ссылка можно просто создать отдельное get_r1 функция в A1, который делает то, в чем Вы нуждаетесь.

class A1: public AInterface
{
  public:
     boost::shared_ptr<RetInterface> get_r() const
     {
         return get_r1();
     }
     boost::shared_ptr<Ret1> get_r1() const {...}
     ...
};

, С другой стороны, можно использовать шаблон "посетитель" или что-то как мой Динамическая Двойная Отправка техника для передачи обратного вызова в возвращенному объекту, который может тогда вызвать обратный вызов с корректным типом.

24
ответ дан Anthony Williams 24 November 2019 в 16:29
поделиться

Вы не можете изменить типы возврата (для неуказательных, нессылочных типов возврата) при перегрузке методов в C++. A1::get_r должен возвратиться boost::shared_ptr<RetInterface>.

у Anthony Williams есть хорошее всестороннее ответ .

1
ответ дан Community 24 November 2019 в 16:29
поделиться

г-н Fooz ответил на часть 1 Вашего вопроса. Часть 2, это прокладывает себе путь, потому что компилятор не знает, будет ли это называть AInterface:: get_r или A1:: get_r во время компиляции - это должно знать, какое возвращаемое значение это собирается получить, таким образом, это настаивает на обоих методах, возвращая тот же тип. Это - часть спецификации C++.

Для обходного решения, если A1:: get_r возвращает указатель на RetInterface, виртуальные методы в RetInterface будут все еще работать как ожидалось, и надлежащий объект будет удален, когда указатель будет уничтожен. Нет никакой потребности в различных типах возврата.

-1
ответ дан Community 24 November 2019 в 16:29
поделиться

возможно, вы могли бы использовать параметр out, чтобы обойти «ковариацию с возвращаемыми boost shared_ptrs.

 void get_r_to(boost::shared_ptr<RetInterface>& ) ...

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

-1
ответ дан 24 November 2019 в 16:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: