Reputation: 451
Is it possible to specify which constructor to use when inheriting from a template based class? It seems like a basic thing, but I can't seem to figure out how to accomplish this in C++...
In the following code, I want to use a non-default constructor for the PlayerStats object when I create a PlayerActor (which inherits from the BaseActor template class).
class BaseStats {
public:
BaseStats ()
{
}
private:
};
class MonsterStats : public BaseStats {
public:
MonsterStats()
{
}
private:
};
class PlayerStats : public BaseStats {
public:
PlayerStats(
const bool is_new) :
m_is_new(is_new)
{
}
private:
const bool m_is_new;
PlayerStats(); //Don't want this being used...
};
template <class ActorStatsClass>
class BaseActor
{
public:
BaseActor()
{
}
private:
ActorStatsClass m_stats;
};
class MonsterActor: public BaseActor<MonsterStats> {
public:
MonsterActor()
{
}
private:
};
// This is where I'm not sure how to tell the template to use a non-default constructor...
// I get an error saying "PlayerStats::PlayerStats": cannot access private member declared in "PlayerStats". (Which is intended, but I don't want it to try and use the default constructor...)
class PlayerActor : public BaseActor<PlayerStats> {
public:
PlayerActor(const bool is_new)
{
}
private:
PlayerActor(); // Don't use this...
};
Upvotes: 3
Views: 174
Reputation: 66942
template <class ActorStatsClass>
class BaseActor
{
public:
BaseActor()
{
}
private:
ActorStatsClass m_stats;
};
If this BaseActor
class is going to have arbitrary members, it needs ways to construct those arbitrary members. So it needs a generic constructor.
template <class ActorStatsClass>
class BaseActor
{
public:
template<class...Us>
BaseActor(Us&&...vs)
: m_stats(std::forward<Us>(vs)...)
{ }
private:
ActorStatsClass m_stats;
};
This uses forwarding, that whatever parameters are passed to BaseActor
, it just passes them directly to constructing the m_stats
member.
This allows:
class PlayerActor : public BaseActor<PlayerStats> {
public:
PlayerActor(const bool is_new)
: BaseActor<PlayerStats>(is_new)
{ }
PlayerActor() = delete; // Note: this is better than making it private
};
Upvotes: 5
Reputation: 137
your template only says which type to use you need to define which constructor to use with the object itself. for example:
template <class ActorStatsClass>
class BaseActor
{
public:
BaseActor():m_stats(arguments)//call a constructor of m_stats when creating an instance of this class
{
}
private:
ActorStatsClass m_stats;
};
Upvotes: 1