I would like to have the mutators (setters) in my class to return this
to allow for jQuery-like a.name("something").address("somethingelse");
I have a parent class (Entity
) and several childclasses (Client, Agent etc.
). The mutators for most things are inherited from the Entity
class (like name or address), but they return an Entity
object, so I can't call Client mutators on them.
In other words:
// name mutator
Entity& Entity::name( const string& name ) {
// [...] checks
_name = name;
return *this;
}
// budgetRange mutator
Client& Client::budgetRange( const long int& range ) {
// [...] checks
_budgetRange = range;
return *this;
}
then when I call it:
Client a; a.name("UserName123").budgetRange(50);
The compiler (logically) says, that the Entity object has no budgetRange member (because name returns an Entity, not a Client).
My question now is: how could I implement something like this? I thought about overloading all the Entity functions in the childclasses but that wouldn't be nice and would be against the idea of inheritance :)
Thank you in advance for your ideas :D
You should use the CRTP.
template<class Derived>
class Entity
{
Derived* This() { return static_cast<Derived*>(this); }
public:
Derived& name(const string& name)
{
...
return *This();
}
};
class Client : public Entity<Client>
{
public:
Client& budgetRange(const long& range)
{
...
return *this;
}
};
If you want to use virtual functions, you can also add abstract base class, like this:
class AbstractEntity
{
public:
virtual void foo() = 0;
virtual ~AbstractEntity();
};
template<class Derived>
class Entity : AbstractEntity
{...};