Calling derived class constructor from base class - c++

given this code, (I use different code with constructors, destructors, virtuals, etc.), how would one implement A::createChild which adds a pointer to either B or C
#include <vector>
#include <cassert>
class A {
void createChild(std::vector<A *>);
};
void A::createChild(std::vector<A *>) {
//What code goes here?
}
class B : A {};
class C : A {};
int main() {
std::vector<A *> ptrs;
ptrs.push_back(new B);
ptrs.push_back(new C);
ptrs[0]->createChild(ptrs); //Should add a new class of B to ptrs
ptrs[1]->createChild(ptrs); //Should add a new class of C to ptrs
assert(typeid(ptrs[2])==typeid(ptrs[0]);
assert(typeid(ptrs[3])==typeid(ptrs[1]);
}

You may use a template function to achieve that:
class A {
template<typename Derived>
void createChild(std::vector<A *>);
};
template<typename Derived>
void A::createChild(std::vector<A *> v) {
v.push_back(new Derived);
}

Related

How to casting class template based on template argument type

Currently, I store pointers of different types in a vector. To archive this, I implemented a class template "Store" which derives from a non-class template "IStore". My vector finally stores pointers to "IStore".
In code:
class IStore
{
public:
IStore() = default;
virtual ~IStore() = default;
virtual void call() = 0;
// ... other virtual methods
};
template<typename T>
class Store : public IStore
{
public:
Store() = default;
virtual ~Store() = default;
virtual void call() override;
// ... other virtual methods
private:
T* m_object = nullptr;
}
And in my main class which holds the vector:
class Main
{
public:
template<typename T>
void registerObject(T* ptr);
template<typename T>
void callObjects();
// ... other methods
private:
std::vector<IStore*> m_storedObjects;
};
So far the current class structure. To describe the problem I need to introduce the following three example structs:
struct A {}
struct B : public A {}
struct C : {}
Other classes should call the Main::registerObject method with pointers to objects of A, B or C types. This method will then create a new Store<A>, Store<B> resp. Store<C> template class object and inserts this objects pointer to m_storedObjects.
Now the tricky part starts: The method Main::callObjects should be called by other classes with a template argument, such as Main::callObjects<B>(). This should iterate though m_storedObjects and call the IStore::call method for each object, which is of type B or which type B is derived from.
For example:
Main::registerObject<A>(obj1);
Main::registerObject<B>(obj2);
Main::registerObject<C>(obj3);
Main::callObjects<B>();
Should call obj1 and obj2 but not obj3, because C isn't B and B isn't derived from C.
My approaches in Main::callObjects were:
1. Perform dynamic_cast and check against nullptr like:
for(auto store : m_storedObjects)
{
Store<T>* base = dynamic_cast<Store<T>*>(store);
if(base)
{
// ...
}
}
which will only work for the same classes, not derived classes, because Store<B> isn't derived from Store<A>.
2. To overwrite the cast operator in IStore and Store, such that I can specify Store should be castable when the template argument is castable. For example in Store:
template<typename C>
operator Store<C>*()
{
if(std::is_convertible<T, C>::value)
{
return this;
}
else
{
return nullptr;
}
}
But this method is never called.
Does anyone have a solution to this problem?
Sorry for the long post, but I thought more code would be better to understand the problem.
Thanks for your help anyway :)
After some thought, I realized that your type erasure, from assigning Store<T> objects to IStore* pointers, makes it impossible to use any compile-time type checking like std::is_base_of and the like. The next best option you have is run-time type information (dynamic_cast<>(), typeid()). As you observed, dynamic_cast<>() can't determine if an object's type is an ancestor of another type, only if an object's type is a descendant of another type known at compile time.
EDIT: With C++17 support, I can think of another way to solve your problem, based on the std::visit example here. If you change your Main interface...
#include <iostream>
#include <vector>
#include <variant>
template <typename T>
class Store {
public:
using value_type = T;
Store(T* object): m_object(object) {}
void call() { std::cout << "Hello from " << typeid(T).name() << '\n'; }
// ... other methods
private:
T* m_object = nullptr;
};
template <typename... Ts>
class Main {
private:
std::vector<std::variant<Store<Ts>...>> m_storedObjects;
public:
// replacement for registerObjects, if you can take all objects in at once
Main(Ts*... args): m_storedObjects({std::variant<Store<Ts>...>(Store<Ts>{args})...}) {}
template <typename U>
void callObjects() {
for (auto& variant : m_storedObjects) {
std::visit([](auto&& arg) {
using T = typename std::decay_t<decltype(arg)>::value_type;
if constexpr (std::is_base_of<T, U>::value) {
arg.call();
}
}, variant);
}
}
};
struct A {};
struct B : public A {};
struct C {};
int main() {
A a;
B b;
C c;
auto m = Main{&a, &b, &c};
m.callObjects<B>();
// > Hello from 1A
// > Hello from 1B
return 0;
}

Convert class to derived class, without modifying it

I am working with a set of classes A, B, ... These classes are independent except that they have one method in common. Now I want to combine these classes in a vector, to call method in one loop. It seems that the best solution is to make the classes derived classes from some Parent (see below).
Now the question is the following. I want to create a header-only library for each class (a.h, b.h, ...). There I want the classes to be completely independent. Only in the main module I want to 'attach' the classes to a Parent to be able to combine them in a vector. How do I do this? Or do I have to resort to a vector of void* pointers? Or is there another way to combine these classes in a vector?
Classes in list: with parent/child paradigm
Here is what I have been able to do to combine the classes in the vector. Note I specifically want to avoid the parent/child paradigm in the class definitions. But I still want to combine them in a vector.
#include <iostream>
#include <vector>
#include <memory>
class Parent
{
public:
virtual ~Parent(){};
virtual void method(){};
};
class A : public Parent
{
public:
A(){};
~A(){};
void method(){};
};
class B : public Parent
{
public:
B(){};
~B(){};
void method(){};
};
int main()
{
std::vector<std::unique_ptr<Parent>> vec;
vec.push_back(std::unique_ptr<Parent>(new A));
vec.push_back(std::unique_ptr<Parent>(new A));
vec.push_back(std::unique_ptr<Parent>(new B));
for ( auto &i: vec )
i->method();
return 0;
}
Compile using e.g.
clang++ -std=c++14 main.cpp
A possible solution based on type erasure, static member functions and pointers to void that doesn't make use of virtual at all (example code, far from being production-ready):
#include <iostream>
#include <vector>
struct Erased
{
using fn_type = void(*)(void *);
template<typename T>
static void proto(void *ptr) {
static_cast<T*>(ptr)->method();
}
fn_type method;
void *ptr;
};
struct A
{
void method(){ std::cout << "A" << std::endl; };
};
struct B
{
void method(){ std::cout << "B" << std::endl; };
};
int main()
{
std::vector<Erased> vec;
vec.push_back(Erased{ &Erased::proto<A>, new A });
vec.push_back(Erased{ &Erased::proto<B>, new B });
for ( auto &erased: vec ) {
erased.method(erased.ptr);
}
return 0;
}
This can help to avoid using a common base class. See it on wandbox.
As mentioned in the comments, here is a slightly modified version that adds create and invoke methods to reduce the boilerplate for the users.
This is more of a pseudocode, trivial details are omitted.
struct HolderBase
{
virtual void foo() = 0;
};
template <class T>
struct Holder : HolderBase
{
Holder(T* t) : t(t) {}
T* t;
void foo() { t->foo(); }
};
std::vector<HolderBase*> v { new Holder<A>(new A), new Holder<B>(new B) };
You can also have a variant of Holder that holds an object by value (and mix both variants in the same vector freely).
If you have a single method to call, there is a much simpler solution:
A a;
B b;
std::vector<std::function<void()> v { [](){a.foo();}, [](){b.foo();} };
You want to erase the type of the objects and treat them uniformly, so naturally type erasure is the solution.
class with_method_t {
struct model_t {
virtual ~model_t() = default;
virtual void call_method() = 0;
};
template<class C>
class concept_t final : public model_t {
C obj;
public:
concept_t(C const& c) : obj{c} {}
concept_t(C&& c) : obj{std::move(c)} {}
void call_method() override { obj.method(); }
};
std::unique_ptr<model_t> instance;
public:
template<class C>
with_method_t(C&& arg)
: instance{std::make_unique<concept_t<C>>(std::forward<C>(arg))}
{}
void method() { instance->call_method(); }
};
Then have yourself a vector of with_method_t which is a value type. No raw dynamic allocation or de-allocation. The instance is build by forwarding the argument it receives into a small polymorphic container:
std::vector<with_method_t> vec;
vec.emplace_back(A{});
vec.emplace_back(B{});
for ( auto &i: vec )
i.method();

Iterate over different CRTP Derived class methods

In an example below I have a pretty typical CRTP example, two different derived classes that both have a method bar. The base class has a method foo which just forwards to some derived bar method
#include <iostream>
template<typename Derived>
class Base {
public:
void foo() {
static_cast<Derived*>(this)->bar();
}
};
class DerivedA : public Base<DerivedA> {
public:
void bar() {
::std::cout << "A\n";
}
};
class DerivedB : public Base<DerivedB> {
public:
void bar() {
::std::cout << "B\n";
}
};
int main() {
DerivedA a;
DerivedB b;
a.foo();
b.foo();
}
It doesn't seem like I can have an array / vector / etc. of the base class because it would have to have a type along the lines of Base<T> where T is different
Is there some kind of convention without virtual for being able to iterate over different derived classes assuming they all have the same method (bar in this case)?
You can use Boost.Variant. For example:
typedef boost::variant<DerivedA, DerivedB> Derived;
struct BarCaller : public boost::static_visitor<void> {
template <class T>
void operator()(T& obj) {
obj.bar();
}
};
int main() {
std::vector<Derived> vec{DerivedA(), DerivedB(), DerivedA()};
BarCaller bar;
for (Derived& obj : vec) {
obj.apply_visitor(bar);
}
}
This lets you store heterogeneous types in a vector or other STL container (by using a "discriminated union"), and lets you call a specific function on all of them regardless of their not having a common ancestor or any virtual methods.
It doesn't seem like I can have an array / vector / etc. of the base class because it would have to have a type along the lines of Base<T> where T is different.
You can have a base class of Base<T> for all T, then, you can have a list/vector/array of pointers to the base class, if that works for you.
struct BaseOne
{
virtual void foo() = 0;
virtual ~BaseOne() {}
};
template<typename Derived>
class Base : struct BaseOne {
public:
void foo() {
static_cast<Derived*>(this)->bar();
}
};
and then,
int main() {
std::vector<BaseOne*> v {new DerivedA, new DerivedB };
for ( auto item : v )
item->bar();
for ( auto item : v )
delete item;
}
Is there some kind of convention without virtual for being able to iterate over different derived classes assuming they all have the same method (bar in this case)?
No, there isn't.
As per now, variant has became part of the C++17 standard and the solution to the problem can be solved by std::variant and std::visit as follows.
The template class in the example is Interface<> and use the CRTP idiom to force derived class to implement helloImpl():
#include <iostream>
#include <vector>
#include <variant>
template<typename Implementer>
struct Interface {
void hello() const {
static_cast<Implementer const *>(this)->helloImpl();
}
};
A couple of class examples with different implementations of helloImpl()
struct Hello1 : public Interface<Hello1> {
void helloImpl() const {
std::cout << "Hello1" << std::endl;
}
};
struct Hello2 : public Interface<Hello2> {
void helloImpl() const {
std::cout << "Hello2" << std::endl;
}
};
And here is how to use it to store data in a vector<> container and its traversal:
int main() {
using var_t = std::variant<Hello1, Hello2>;
std::vector<var_t> items{Hello1(), Hello1(), Hello2()};
for(auto &item: items) {
std::visit([](auto &&arg) {
arg.hello();
}, item);
}
return 0;
}

Subclass of class that inherits from enable_shared_from_this returning shared_ptr of self

I'm wondering if there is anyway to do something like this pseudo code:
class A : public std::enable_shared_from_this<A> {
public:
std::shared_ptr<self_t> getPtr(){
return std::static_pointer_cast<self_t>(shared_from_this());
}
};
class B : public A {
std::vector<A> container;
std::shared_ptr<self_t> addChild(A child){
container.push_back(child);
return getPtr();
}
};
class C : public B {
public:
std::shared_ptr<self_t> doSomething(){
// something
return getPtr();
}
};
int main(){
A obja = new A();
C obj = new C();
obj->addChild(obja)->doSomething()
}
My goal is that an object represents a view (as in the V in MVC), and for methods to be able to return itself for chained calling. Eg: ->setTop(0)->addChild(child1)->setBottom(0).
I've read that it may be more approachable to do something like overloading the << operator, but I don't see that working to well or looking very pretty.
One thought I had was to make a macro called VIEW(name,parent) that would use templates to expand out, but I had issue with self-refferental default template arguments.
Any help would be greatly appreciated.
-- edit --
In a nut shell, I'm hoping to have a base class inherit from enable_shared_from_this. The base class would have a method such as doSomething that returns the shared pointer. When a derived class inherits from the base class, I want the doSomething method to return a shared pointer to the derived class. I want to be able to do this without overriding doSomething in the derived class.
This kind of concept would be covered by extension methods which exist outside a class definition, do not violate the class permissions but can be called like a method... which exists in C# but not currently in C++. The code in C# looks like this:
// c# syntax
namespace MyBaseExtensions {
public static class MyBaseExt {
public static shared_ptr<T> getPtr<T>(this T self) where T : MyBase
{
return static_pointer_cast<T>(self.shared_from_this());
}
}
}
This allows for operator chaining because each inheritance of a class line MyBase would have its own definition of the function because the function is not an inherited method but instead applied directly to each related type.
The argument against is that extensions pollute the object with often unneeded functionality and that a standalone template function will do the same thing. The issue is that with that logic:
int main(){
A obja = new A();
C obj = new C();
obj->getPtr()->addChild(obja)->doSomething()
}
ends up looking like
int main(){
A obja = new A();
C obj = new C();
doSomething(addChild(getPtr(obj),obja)); //eyeroll.
}
and you would still be declaring the template functions such like
// C++ syntax
namespace MyBaseExtensions {
template<typename T> std::shared_ptr<T> getPtr<T>(T self)
{
return std::static_pointer_cast<T>(self->shared_from_this());
}
}
As for a simple internal way of applying a template uniquely to each derived type, I am not sure of any. The reason for this is that the functionality you want is not method inheritance but that each future class inherits a template which it automatically specializes(and of which the resulting method is either not inherited or hidden.) For that purpose C++ classes would need to have non-inherited specialized public methods, which are not covered by the current access permissions public, private, and protected or template capabilities.
I would be overjoyed to find a nice way to pull off operator chaining.
And since I have gone and wasted your time I made an attempt at this:
#include <vector>
#include <memory>
// 0 argument, creates an overload method (and hides parent class method)
// from template method func_name
// template method specialization of a parent method does not work
// so we use C++11 automatic type deduction to figure the
// template return type and return what the template returns
#define FUNC_DEF_0(base, cur, func_name) \
auto func_name() \
-> decltype(base().func_name<cur>()) { \
return base::func_name<cur>(); \
}
// 1 argument
#define FUNC_DEF_1(base, cur, func_name, arg1_t) \
auto func_name(arg1_t param1) \
-> decltype(base().func_name<cur>(param1)) { \
return base::func_name<cur>(param1); \
}
// class A
// add to class to hide class A methods
#define HIDE_A(current) \
FUNC_DEF_0(A, current, getPtr)
class A : public std::enable_shared_from_this<A> {
public:
template<typename _T = A>
std::shared_ptr<_T> getPtr(){
return std::static_pointer_cast<_T>(shared_from_this());
}
};
// class B
// add to class to hide class B methods with new methods
#define HIDE_B(current) \
HIDE_A(current) \
FUNC_DEF_1(B, current, addChild, A)
class B : public A {
public:
std::vector<A> container;
template<typename _T = B>
std::shared_ptr<_T> addChild(A child){
container.push_back(child);
return A::getPtr<_T>();
}
HIDE_A(B); // hide A methods with B specialized methods
// Example method hiding
// auto getPtr() -> decltype(A().getPtr<B>()) {
// return base::getPtr<B>();
// }
};
// class C
// add to class to hide class C methods
#define HIDE_C(current) \
HIDE_B(current) \
FUNC_DEF_0(C, current, doSomething)
class C : public B {
public:
template<typename _T = C>
std::shared_ptr<_T> doSomething(){
// something
return A::getPtr<_T>();
}
HIDE_B(C); // hide B methods
};
int main() {
auto obja = std::make_shared<A>();
auto obj = std::make_shared<C>();
obj->addChild(*obja)->doSomething();
}
Edit: Fixed attempt. Compiles for me.
class A;
struct virtual_enable_shared_from_this_base :
std::enable_shared_from_this<virtual_enable_shared_from_this_base> {
virtual ~virtual_enable_shared_from_this_base() {}
};
#define HIDE_AMix(type) \
using type::getPtr;
template<typename _T>
class AMix : public virtual virtual_enable_shared_from_this_base {
public:
std::shared_ptr<_T> getPtr() {
auto sptr = shared_from_this();
return std::dynamic_pointer_cast<_T>(sptr);
}
};
#define HIDE_BMix(type) \
HIDE_AMix(type) \
using type::addChild;
template<typename _T>
class BMix : public AMix<_T>{
public:
std::vector<std::shared_ptr<A>> container;
std::shared_ptr<_T> addChild(A* child){
container.push_back(child->getPtr());
return getPtr();
}
};
#define HIDE_CMix(type) \
HIDE_BMix(type) \
using type::addChild;
template<typename _T>
class CMix : public BMix<_T>{
public:
std::shared_ptr<_T> doSomething(){
// something
return getPtr();
}
};
class A : public AMix<A> {
public:
};
class B : public A, public BMix<B> {
public:
HIDE_AMix(BMix<B>);
//using BMix<B>::getPtr;
//using BMix<B>::addChild;
};
class C : public B, public CMix<C> {
public:
HIDE_BMix(CMix<C>);
//using CMix<C>::getPtr;
//using CMix<C>::addChild;
//using CMix<C>::doSomething;
};
int main() {
auto obja = std::make_shared<B>();
auto obj = std::make_shared<C>();
obja->getPtr();
obj->addChild(obja.get())->doSomething();
}
Edit2: Here is another version from fiddling around with templates.
Here is an example of what you may be trying to accomplish (though I'm not sure I 100% understood your requirements or reasoning for this design). Hope it helps...
#include <iostream>
#include <memory>
#include <vector>
class MyBase;
typedef std::shared_ptr<MyBase> MyBaseSharedPtr;
class MyBase : public std::enable_shared_from_this<MyBase> {
public:
MyBaseSharedPtr getPtr() { return shared_from_this(); }
virtual MyBaseSharedPtr doSomething() { return getPtr(); };
virtual MyBaseSharedPtr addChild(MyBaseSharedPtr child) { return getPtr(); };
};
class MyDerived1 : public MyBase {
private:
std::vector<MyBaseSharedPtr> container;
public:
MyBaseSharedPtr addChild(MyBaseSharedPtr child) {
container.push_back(child);
std::cout << "class MyDerived1: adding child\n";
return getPtr();
};
virtual MyBaseSharedPtr doSomething() {
std::cout << "class MyDerived1: doing something\n";
return getPtr();
}
};
class MyDerived2 : public MyDerived1 {
public:
MyBaseSharedPtr doSomething() {
std::cout << "class MyDerived2: doing something\n";
return getPtr();
}
};
int main(void ) {
MyBaseSharedPtr myBase = std::make_shared<MyBase>();
MyBaseSharedPtr myDerived2 = std::make_shared<MyDerived2>();
myDerived2->addChild(myBase)->doSomething();
return 0;
}
template<typename _T>
shared_ptr<_T> allocate()
{
shared_ptr<_T> ptr(new _T);
// this may need to be changed to
// something like (*typename ptr.get()).weak_this
// if the compiler won't accept a duck-typed _T::weak_this
ptr.get()->weak_this = weak_ptr<_T>(ptr);
return ptr;
}
class A
{
weak_ptr<A> weak_this;
friend shared_ptr<A> allocate<A>();
public:
shared_ptr<A> getPtr(){return weak_this.lock();}
shared_ptr<A> doSomething()
{
// do something
return getPtr();
}
};
Based on your example, if what you really want is to be able to extend functionality without exploding multiple inheritance hierarchies and without overwriting each method everywhere, you could try composed functionality with templates. Something like this:
#include <list>
#include <iostream>
struct Base {
};
template <class Parent>
struct A : Parent {
std::list<Parent*> children;
A* addChild(Parent* child) {
children.push_back(child);
return this;
}
};
template <class Parent>
struct B : Parent {
B* doSomething() {
std::cout << "Something" << std::endl;
return this;
}
};
int main(){
typedef A< B<Base> > Composed;
Composed a;
Composed b;
a.addChild(&b)->doSomething();
}
Note, however, that this has the restriction that forces a use order based on the order you compose the "functionality" (classes).
That is, in this example, you can't do:
a.doSomething()->addChild(&b); //ERROR! B is not a A
But this would work if you declare:
typedef B< A<Base> > Composed; //Note the order of B and A
I don't know if it suits your needs.
Hope this helps, at least, to enable you to think the problem in a different way.

looking for solution of c++ member function override (non virtual)

I've two classes:
struct A {
template <typename T>
void print(T& t){
// do sth specific for A
}
};
struct B : A {
template <typename T>
void print(T& t){
// do sth specific for B
}
};
In such case, the more general Base class with virtual functions (which A and B both inherit from) cannot be compiled, since there is no virtual for template. As I try to delegate generally all A or B objects under same "interface", does anyone has the idea to resolve such problem? Thank you in advance.
Sincerely,
Jun
You can think about using using CRTP.
template<typename Derived>
struct Base {
template <typename T>
void print(T& t){
static_cast<Derived*>(this)->print(t);
}
};
struct A : Base<A> {
// template print
};
struct B : Base<B> {
// template print
};
Example Usage:
template<typename T, typename ARG>
void foo (Base<T>* p, ARG &a)
{
p->print(a);
}
This method will be called as,
foo(pA, i); // pA is A*, i is int
foo(pB, d); // pB is B*, d is double
Here is another demo code.
Using a proxy class to get B's method
class A {
public:
friend class CProxyB;
virtual CProxyB* GetCProxyB() = 0;
};
class B;
class CProxyB
{
public:
CProxyB(B* b){mb = b;}
template <typename T>
void printB(T& t)
{
mb->print(t);
}
B* mb;
};
class B:public A {
public:
virtual CProxyB* GetCProxyB(){return new CProxyB(this);};
template <typename T>
void print(T& t){
printf("OK!!!!!\n");
}
};
int _tmain(int argc, _TCHAR* argv[])
{
A* a = new B;
CProxyB* pb = a->GetCProxyB();
int t = 0;
pb->printB(t);
return 0;
}
Two options:
Option one: Virtualize the method where if the user does not provide an implementation, the Base class' is used.
template <typename T>
struct A {
virtual void print(T& t);
};
template <typename T>
void A::print(T& t) {
// do sth specific for A
}
template <typename T>
struct B : A {
virtual void print(T& t);
};
void B::print(T& t) {
// do sth specific for B
}
Option two: Abstract the method where if the user does not provide an implementation, the code will not compile.
template <typename T>
struct A {
virtual void print(T& t)=0;
};
template <typename T>
struct B : A {
virtual void print(T& t){
// do sth specific for B
}
};
template <typename T>
void B::print(T& t){
// do sth specific for B
}
Other than the above mentioned, if you do not make them virtual, the Derived class will Shadow the Base class method and that is most certainly not what you intended. Hence, impossible.
my question is how to use single pointer to different A or B objects.
You can do this without virtual functions per-se. But all you will really be doing is writing an implementation of a V-table and virtual functions.
If I were going to manually implement virtual functions, I would base it all on a Boost.Variant object. The variant would effectively hold the member data for each class. To call a function, you use a variant visitor functor. Each "virtual function" would have its own visitor functor, which would have different overloads of operator() for each of the possible types within the variant.
So you might have this:
typedef boost::variant<StructA, StructB, StructC> VirtualClass;
You could store any one of those objects in the variant. You would call a "virtual function" on the object like this:
VirtualClass someObject(StructA());
boost::apply_visitor(FunctorA(), someObject);
The class FunctorA is your virtual function implementation. It is a visitor, defined like this:
class FunctorA : public boost::static_visitor<>
{
void operator()(StructA &arg){
//Do something for StructA
}
void operator()(StructB &arg){
//Do something for StructB
}
void operator()(StructC &arg){
//Do something for StructC
}
}
Visitors can have return values, which are returned by apply_visitor. They can take arguments, by storing the arguments as members of the visitor class. And so forth.
Best of all, if you ever change your variant type, to add new "derived classes", you will get compiler errors for any functors that don't have overloads for the new types.
But to be honest, you should just be using virtual functions.
By using CRTP(Curiously recurring template pattern), you can achieve static polymorphsim without virtual.
#include <iostream>
using namespace std;
#define MSG(msg) cout << msg << endl;
template<class Derived>
class Base{
public:
void print()
{
static_cast<Derived*>(this)->print();
}
};
class Derived1 : public Base<Derived1>
{
public:
void print()
{
MSG("Derived 1::print");
}
};
class Derived2 : public Base<Derived2>
{
public:
void print()
{
MSG("Derived 2::print");
}
};
template<class T>
void callme(Base<T>& p)
{
p.print();
}
int main()
{
Base<Derived1> p1;
Base<Derived2> p2;
callme(p1);
callme(p2);
system("pause");
return 0;
}
//Result :
//Derived 1::print
//Derived 2::print