Исключение нулевого указателя генерируется, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:
null
. null
. null
, как если бы это был массив. null
, как если бы это был массив. null
как будто это было значение Throwable. Приложения должны бросать экземпляры этого класса, чтобы указать на другие незаконные использования объекта null
.
Ссылка: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html
Во-первых, это действительно, как это работает в 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 {...}
...
};
, С другой стороны, можно использовать шаблон "посетитель" или что-то как мой Динамическая Двойная Отправка техника для передачи обратного вызова в возвращенному объекту, который может тогда вызвать обратный вызов с корректным типом.
Вы не можете изменить типы возврата (для неуказательных, нессылочных типов возврата) при перегрузке методов в C++. A1::get_r
должен возвратиться boost::shared_ptr<RetInterface>
.
у Anthony Williams есть хорошее всестороннее ответ .
г-н Fooz ответил на часть 1 Вашего вопроса. Часть 2, это прокладывает себе путь, потому что компилятор не знает, будет ли это называть AInterface:: get_r или A1:: get_r во время компиляции - это должно знать, какое возвращаемое значение это собирается получить, таким образом, это настаивает на обоих методах, возвращая тот же тип. Это - часть спецификации C++.
Для обходного решения, если A1:: get_r возвращает указатель на RetInterface, виртуальные методы в RetInterface будут все еще работать как ожидалось, и надлежащий объект будет удален, когда указатель будет уничтожен. Нет никакой потребности в различных типах возврата.
возможно, вы могли бы использовать параметр out, чтобы обойти «ковариацию с возвращаемыми boost shared_ptrs.
void get_r_to(boost::shared_ptr<RetInterface>& ) ...
, поскольку я подозреваю, что вызывающий может использовать более усовершенствованный тип shared_ptr в качестве аргумента.