Access Overridden Field In Constructor Without Templates
Solution 1:
Despite you're asking to do this without templates, it's the only way to do this from a base class constructor.
Here's a sample how it should be done:
structIDriver {
// Public virtual API:virtualvoidfunc1()= 0;
// ...virtual ~IDriver() {}
};
template<typename Derived>
classDriver : public IDriver {
public:
Driver() {
std::cout << "Driver" << std::endl;
std::cout << static_cast<Derived*>(this)->name() << std::endl;
}
};
classSpecificDriver : public Driver<SpecificDriver> {
public:
// Public virtual API:virtualvoidfunc1();
std::string name()const{ return"SpecificDriver"; }
// or use typeid(SpecificDriver).name() if you prefer
};
intmain(){
SpecificDriver sd;
}
As for your comment:
Is it possible to use additional init() function as in @tobspr method, but making name a field instead of function call?
Well, since the class name is a static property of these classes anyway, you can use a static const
field like follows:
template<typename Derived>
classDriver : public IDriver {
public:
Driver() {
std::cout << name << std::endl;
std::cout << Derived::name << std::endl;
}
private:
staticconst std::string name;
};
template<typename Derived>
const std::string Driver<Derived>::name = "Driver";
classSpecificDriver : public Driver<SpecificDriver> {
public:
staticconst std::string name;
};
const std::string SpecificDriver::name = "SpecificDriver";
intmain(){
SpecificDriver sd;
}
or even simplified use typeid()
:
#include<iostream>#include<string>#include<typeinfo>template<typename Derived>
classDriver {
public:
Driver() {
std::cout << typeid(*this).name() << std::endl;
std::cout << typeid(Derived).name() << std::endl;
}
};
classSpecificDriver : public Driver<SpecificDriver> {
};
intmain(){
SpecificDriver sd;
}
Solution 2:
Assuming you have two classes Base and Derived, the Base constructor does not know anything about the Derived class, which makes it impossible to distinguish between both types.
Since you also can not (should not) call virtual methods in the constructor, a common pattern is to make an init method:
structBase {
virtual std::string get_name(){ return"Base"; }
voidinit(){ std::cout << get_name(); }
};
structDerived : public Base {
virtual std::string get_name(){ return"Derived"; }
};
// Later on ..
Base b;
b.init(); // Should print "Base"
Derived d;
d.init(); // Should print "Derived"
As you can see, this is definitely not the simplest solution. Using templates in this case would certainly be better.
Post a Comment for "Access Overridden Field In Constructor Without Templates"