Для сравнения:
class Base {};
class Derived : public Base {};
Derived d;
Base* p = &d; // points to a Base that in reality is a derived
Base& b = d; // in this respect, references do not differ...
// and you can get the original type back:
auto dr = static_cast<Derived&>(b); // if you know 100% for sure that b is a Derived
auto dp = dynamic_cast<Derived*>(p); // if p might point to another type; you get
// a null pointer back, if it does
Нет абсолютно никакой разницы с возвратом указателей или ссылок на this
/ *this
, так что да, вы можете смело делать это.
Edit:
Circle().SetStrokeWidth(16).SetCircleCenter({0, 0})
. SetStrokeWidth возвращает ссылку на элемент, поэтому SetCircleCenter недоступен.
В этом случае у вас все же проблемы. Поскольку lubgr уже обозначено , вы можете решить эту проблему, переопределив кооперируемый тип возврата - и да, это будет означать, что вам придется переопределять каждую функцию отдельно. Кроме того, вы можете сохранить весь этот подход, используя CRTP :
template <typename T>
class SomeAppropriateName : public Element
{
public:
T& setStrokeWidth(unsigned int width)
{
Element::setStrokeWidth(width);
return static_cast<T&>(*this);
}
};
class Circle : public SomeAppropriateName<Circle>
{
// the overrides needed are inherited...
};
Для этого подхода оригинальные функции из класса Element
должны быть не виртуальными (на самом деле это преимущество, поскольку вызовы виртуальных функций обходятся дороже ...); в шаблоне аргумент (T
, т. е. Circle
) еще не полностью определен (с шаблоном CRTP), и компилятор не сможет проверить, действительно ли возвращаемый тип является ко-вариантным. Так что на самом деле мы просто следим за функцией базового класса.
Это все же не является недостатком по сравнению с переопределением: ко-вариантный тип возврата будет доступен только в том случае, если (виртуальная) функция вызывается непосредственно для объекта:
Circle c;
c.setStrokeWidth(7).setCenter();
Element& e = c;
e.setStrokeWidth(7).setCenter(); // fails, even if you implement co-variant override directly