For comparison:
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
There is absolutely no difference with returning pointers or references to this/*this, so yes, you can safely do so.
Edit:
Circle().SetStrokeWidth(16).SetCircleCenter({0, 0}). SetStrokeWidth returns a reference to Element, so SetCircleCenter is unavailable.
In this case, you are a bit in trouble, though. As lubgr denoted already, you can solve the issue by overriding with co-variant return type – and yes, this would mean that you'd have to override each function separately. Alternatively, you can save all this hassle using 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...
};
For this approach, original functions from Element class need to be non-virtual (thanks @Quentin for the hint; actually an advantage as virtual function calls are more costly...); in the template, the argument (T, i. e. Circle) is not yet completely defined (with CRTP pattern) and the compiler wouldn't be able to check if the return type really is co-variant. So actually, we are just shadowing the base class' function.
This is still no disadvantage compared to overriding: The co-variant return type will only be available if the (virtual) function is called on the object directly anyway:
Circle c;
c.setStrokeWidth(7).setCenter();
Element& e = c;
e.setStrokeWidth(7).setCenter(); // fails with both variants, i.e. even if you
// implement co-variant override