I want using polymorphism in C++, I am try to extract method shows in all derived class into base class.
For example:
I have two class, HouseA and HouseB, they are template class.
And they are derived from base class BaseHouse.
class BaseHouse
{
public:
//other thing
private:
};
template <typename Type>
class HouseA : public BaseHouse
{
public:
HouseA(Type object_input) : object(object_input)
{
}
// other thing about HouseA
Type &getObject()
{
std::cout << "this is House A" << std::endl;
return object;
}
private:
Type object;
};
template <typename Type>
class HouseB : public BaseHouse
{
public:
HouseB(Type object_input) : object(object_input)
{
}
// other thing about HouseB
Type &getObject()
{
std::cout << "this is House B" << std::endl;
return object;
}
private:
Type object;
};
Bacause of polymorphism, we using base class's pointer to access derivated class object. When I need to call method defined in derivated class, I am always transfer base class pointer into derivated class pointer:
int main()
{
HouseA<int> house_a(5);
int x = house_a.getObject();
BaseHouse *base_ptr = &house_a;
// suppose after some complicate calculate calculation
// we only have the base class pointer can access derivated class object
HouseA<int> *ptr_a = (HouseA<int> *)base_ptr; //transfer base class pointer into derivated class pointer
ptr_a->getObject();
return 0;
}
But the derived class HouseA and HouseB both have the method getObject.
So I want to extract template derived class's method into non-template base class.
For some reason, we suppose that the base class BaseHouse can not be template class.
Is there any way I can do that?
Thanks in advance.
If the signature of the derived member depends on the template arguments (as your getObject does on Type) the member cannot be extracted into a non-template base. At least not without removing the ability of the member's signature to vary based on template arguments.
Maybe not exactly a classical Visitor, but...
Okay, the basic idea is we have to somehow capture and encapsulate templated processing into a single entity ready-to-use in a run-time polymorphic construct.
Let's start with a simple class hierarchy:
struct Consumer;
struct Base {
virtual void giveObject(Consumer const &) const = 0;
virtual ~Base() = default;
};
struct Derived1: Base {
Derived1(int x): x(x) {}
void giveObject(Consumer const &c) const override {
c(x);
}
private:
int x;
};
struct Derived2: Base {
Derived2(double y): y(y) {}
void giveObject(Consumer const &c) const override {
c(y);
}
private:
double y;
};
So far, it is very simple: the Base class has a pure virtual method that accepts an object of type Consumer and a concrete implementation of this method is expected to expose to Consumer the relevant part of the internal state of its particular implementor (which is a subtype of Base). In other words, we have taken that 'virtual template' idiom and hid it inside the Consumer. Ok, what could it possibly be?
First option, if you know in advance at compile-time (at source code-time, more exactly) what it could possibly do, i.e. there's only one algorithm of consumption per each object type, and the set of types is fixed, it is quite straightforward:
struct Consumer {
void consume(int x) const { std::cout << x << " is an int.\n"; }
void consume(double y) const { std::cout << y << " is a double.\n"; }
template<typename T> void consume(T t) const {
std::cout << "Default implementation called for an unknown type.\n";
}
};
etc.
More elaborate implementation would allow run-time construction of a templated entity. How is that even possible?
Alexandrescu in his "Modern C++ Design" uses typeid to store particular type handlers in a single data structure. In a brief, this could be something like:
struct Handler {
virtual ~Handler() = default; // now it's an empty polymorphic base
};
template<typename T> struct RealHandler: Handler {
RealHandler(std::function<void(T)> f): f(std::move(f)) {}
void handle(T x) {
f(x);
}
private:
std::function<void(T)> f;
};
#include <map>
#include <type_info>
#include <functional>
struct Consumer {
template<typename T> void consume(T t) const {
auto f{knownHandlers.find(typeid(t))};
if(f != knownHandlers.end()) {
RealHandler<T> const &rh{
dynamic_cast<RealHandler<T> const &>(*f->second)};
rh.handle(t);
}
else {
// default implementation for unregistered types here
}
}
template<typename T> Consumer ®ister(std::function<void(T)> f) {
knownHandlers[typeid(T)] = std::make_unique<RealHandler<T>>(std::move(f));
}
private:
std::map<std::type_info, std::unique_ptr<Handler>> knownHandlers;
};
Haven't actually tested it, as I don't like typeids and other RTTI much. What I have quickly tested is another solution that requires neither maps nor typeinfo to store handlers in a templated manner. Still it uses a small trick, like how can we possibly pass, keep and retrieve information of an arbitrary type with the same call.
struct Consumer {
Consumer() {}
template<typename T> void consume(T t) const {
auto f{setSlot<T>()};
if(f) f(t);
else {
// default implementation for an unset slot
std::cout << t / 2 << '\n';
}
}
template<typename T>
std::function<void(T)> &setSlot(
std::function<void(T)> f = std::function<void(T)>{}) const
{
static std::function<void(T)> slot;
if(f) { // setter
slot = std::move(f);
}
return slot;
}
};
Here, setSlot() is used to store a handler for a particular type: when called with a non-empty argument, it stores that argument; and then returns its currently kept value. With Consumer so defined, the class hierarchy from above works as:
int main() {
Consumer c;
c.setSlot<int>([](int x){ std::cout << x << " is an int!\n"; });
Base const &b1{Derived1{42}};
Base const &b2{Derived2{3.14}};
b1.giveObject(c);
b2.giveObject(c);
}
Output:
42 is an int!
1.57
In the first line we see a message printed by a custom int handler; in the second line, a default message is printed for the double type, as no custom handler for double was installed.
One obvious drawback of this implementation is that handlers are stored in static variables thus all Consumers share the same handlers for all types, so Consumer here is actually a monostate. At least, you can change implementations for types at run-time, unlike if you had fixed Consumers of the very first approach. The maps-of-typeids approach from above shouldn't have this drawback, in exchange for some performance cost.
I want to implement a class hierarchy for object dispatching. Different classes dispatch different elements, and each class can dispatch its element represented as different data types.
It is better understood through a (faulty) example. This is what I would like to have if virtual function templating was allowed:
class Dispatcher {
template <class ReturnType>
virtual ReturnType getStuffAs();
};
So that I can implement subclasses as:
class CakeDispatcher : public Dispatcher {
template <>
virtual Recipe getStuffAs(){ ... }
template <>
virtual Baked getStuffAs(){ ... }
};
class DonutDispatcher : public Dispatcher {
template <>
virtual Frozen getStuffAs(){ ... }
template <>
virtual Baked getStuffAs(){ ... }
}
So that I can do the following later on:
void function( Dispatcher * disp ) {
// Works for Donut and Cake, but result will be a different Baked object
Baked b = disp->getStuffAs<Baked>();
// works if disp points to a DonutDispatcher
// fails if it is a CakeDispatcher
// can be compiling/linking time error or runtime error. I don't care
Frozen f = disp->getStuffAs<Frozen>();
}
Requirements/constraints:
All possible return types are not known beforehand. That's why I "need" templates.
Each class can provide just some return types.
Classes must have a common ancestor, so that I can store objects through a pointer to parent class and invoke functions through this pointer.
EDIT: I CAN'T use C++11 features, but I CAN use boost library.
Things I've thought about, but are not a solution:
Obviously, virtual template functions
Curiously Recurring Template Pattern: breaks the condition of common ancestor
Using some kind of traits class containing the functionality of children classes, but it does not work because a non-virtual implementation in the parent class does not have access to this information
I could maybe store some typeid info in the parent class, passed by children on construction. This makes possible for the non-virtual parent dispatching method to dynamic-cast itself to the children type... but it appears to be ugly as hell, and I don't know if this can cause some kind cycle-referencing problem.
class Dispatcher {
private:
typeid(?) childType;
public:
Dispatcher(typeid childT) : childType(childT) {}
// NOT VIRTUAL
template <class ReturnType>
ReturnType getStuffAs()
{
// or something equivalent to this cast, which I doubt is a correct expression
return dynamic_cast<childType *>(this)->childGetStuffAs<ReturnType>();
}
};
Then child classes would implement childGetStuffAs functions, which are not virtual too.
I've read like 5-10 related questions, but none of the provided solutions seems to fit this problem.
Can any of you come up with a better solution?
Is there a standard pattern/technique for solving this problem?
EDIT: The real problem
In the real problem, I have physical models with properties that can be represented in multiple ways: functions, matrices, probability distributions, polynomials, and some others (for example, a non-linear system can be represented as a function but not as a a matrix, while a linear system can be transformed to both).
There are also algorithms which can use those models indistinctly, but they could require specific representations for some model features. That's the reason for the "getStuffAs" function. The whole think is a bit complicated --too much to explain it here properly--, but I can guarantee that in this context the interface is well defined: input, computation and output.
My intention was to make this possible assuming that the number of possible representations is fully defined beforehand, and making it possible to transform the products to already existing types/classes that cannot be modified.
However, i'm starting to realize that this is, indeed, not possible in a simple way --I don't want to write a library just for this problem.
#include <cstdio>
// as a type identifier
struct stuff {
virtual void foo() {}
};
template <typename T>
struct stuff_inh : stuff {
};
struct Dispatcher {
template <typename T>
T* getStuffAs() {
return (T*)((getStuffAsImpl( new stuff_inh<T>() )));
}
virtual void* getStuffAsImpl(void*) = 0;
virtual void type() {printf("type::dispatcher\n");}
};
struct Cake : public Dispatcher {
void* getStuffAsImpl(void* p) {
stuff* s = static_cast<stuff*>(p);
printf("cake impl\n");
if (dynamic_cast<stuff_inh<Cake>*>(s) == NULL) {
throw "bad cast";
}
return (void*)(new Cake());
}
virtual void type() {printf("type::Cake\n");}
};
struct Rabbit : public Dispatcher {
void* getStuffAsImpl(void* p) {
stuff* s = static_cast<stuff*>(p);
printf("rabbit impl\n");
if (dynamic_cast<stuff_inh<Rabbit>*>(s) != NULL) {
return (void*)(new Rabbit());
}
else if (dynamic_cast<stuff_inh<Cake>*>(s) != NULL) {
return (void*)(new Cake());
}
else {
throw "bad cast";
}
}
virtual void type() {printf("type::Rabbit\n");}
};
void foo(Dispatcher* d) {
d->getStuffAs<Cake>()->type();
d->getStuffAs<Rabbit>()->type();
}
int main() {
Rabbit* r = new Rabbit;
foo(r);
Cake* c = new Cake;
foo(c);
}
I an not sure about the correctness of this ugly solution, may it be helpful for you. >_<
deletion of resource is not coded for a clearer look.
My solution is a combination of recurring template and diamond inheritance.
At least it's working. :)
#include <iostream>
class Dispatcher
{
public:
template<class T>
T getStuff()
{
return T();
}
};
template<class T>
class Stuffer : public Dispatcher
{
public:
template<class TT=T>
TT getStuff(){
return reinterpret_cast<TT>(this);
}
};
class Cake{
public:
Cake(){}
void print()
{
std::cout << "Cake" << std::endl;
}
};
class Recipe
{
public:
Recipe(){}
void print()
{
std::cout << "Recipe" << std::endl;
}
};
class CakeRecipe : public Stuffer<Cake>, public Stuffer< Recipe >
{
public:
};
int main()
{
Dispatcher* cr = reinterpret_cast<Dispatcher*>(new CakeRecipe());
cr->getStuff<Cake>().print();
cr->getStuff<Recipe>().print();
getchar();
return 1;
}
I have the code as below. I have a abstract template class Foo and two subclasses (Foo1 and Foo2) which derive from instantiations of the template. I wish to use pointers in my program that can point to either objects of type Foo1 or Foo2, hence I created an interface IFoo.
My problem is I'm not sure how to include functionB in the interface, since it is dependant on the template instantiation. Is it even possible to make functionB accessible via the interface, or am I attempting the impossible?
Thank you very much for your help.
class IFoo {
public:
virtual functionA()=0;
};
template<class T>
class Foo : public IFoo{
public:
functionA(){ do something; };
functionB(T arg){ do something; };
};
class Foo1 : public Foo<int>{
...
};
class Foo2 : public Foo<double>{
...
};
You are actually attempting the impossible.
The very heart of the matter is simple: virtual and template do not mix well.
template is about compile-time code generation. You can think of it as some kind of type-aware macros + a few sprinkled tricks for meta programming.
virtual is about runtime decision, and this require some work.
virtual is usually implemented using a virtual tables (think of a table which lists the methods). The number of methods need be known at compile time and is defined in the base class.
However, with your requirement, we would need a virtual table of infinite size, containing methods for types we haven't seen yet and that will only be defined in the years to come... it's unfortunately impossible.
And if it were possible ?
Well, it just would not make sense. What happens when I call Foo2 with an int ? It's not meant for it! Therefore it breaks the principle that Foo2 implements all the methods from IFoo.
So, it would be better if you stated the real problem, this way we could help you at a design level rather than at a technical level :)
Easiest way is to make your interface templated.
template <class T>
class IFoo {
public:
virtual void functionA()=0;
virtual void functionB(T arg){ do something; };
};
template<class T>
class Foo : public IFoo<T>{
public:
void functionA(){ do something; };
void functionB(T arg){ do something; };
};
Since functionB's argument type must be known in advance, you have only one choice: Make it a type which can hold every possible argument. This is sometimes called a "top type" and the boost libraries have the any type which gets quite close to what a top type would do. Here is what could work:
#include <boost/any.hpp>
#include <iostream>
using namespace boost;
class IFoo {
public:
virtual void functionA()=0;
virtual void functionB(any arg)=0; //<-can hold almost everything
};
template<class T>
class Foo : public IFoo{
public:
void functionA(){ };
void real_functionB(T arg)
{
std::cout << arg << std::endl;
};
// call the real functionB with the actual value in arg
// if there is no T in arg, an exception is thrown!
virtual void functionB(any arg)
{
real_functionB(any_cast<T>(arg));
}
};
int main()
{
Foo<int> f_int;
IFoo &if_int=f_int;
if_int.functionB(10);
Foo<double> f_double;
IFoo &if_double=f_double;
if_int.functionB(10.0);
}
Unfortunately, any_cast does not know about the usual conversions. For example any_cast<double>(any(123)) throws an exception, because it does not even try to convert the integer 123 to a double. If does not care about conversions, because it is impossible to replicate all of them anyway. So there are a couple of limitations, but it is possible to find workarounds if necessary.
I don't think you can get what you want. Think of this if you were to implement your suggestion: if you have a pointer to an IFoo instance and you call functionB(), what type parameter should you give it? The underlying problem is that Foo1::functionB and Foo2::functionB have different signatures and do different things.
You can achieve something comparable by wrapping the IFoo* pointer in a class and exposing the functionality via generic template functions of the non-templated wrapper class:
#include <assert.h>
// interface class
class IFoo {
public:
virtual int type() const = 0; // return an identifier for the template parameter
virtual bool functionA() = 0;
};
// This function returns a unique identifier for each supported T
template <typename T> static int TypeT() { static_assert("not specialized yet"); }
template <> static int TypeT<bool>() { return 0; }
template <> static int TypeT<double>() { return 1; }
//template <> static int TypeT<...>() { ... }
// templated class
template <typename T> class FooT : public IFoo {
public:
int type() const override { return TypeT<T>(); }
bool functionA() override { return true; }
// not in interface
bool functionB(T arg) { return arg == T(); }
};
// function to create an instance of FooT (could also be static function in FooT)
static IFoo* CreateFooT(int type)
{
switch (type)
{
case 0: return new FooT<bool>();
case 1: return new FooT<double>();
//case ...: return new FooT<...>();
default: return nullptr;
}
}
// Non-templated wrapper class
class FooWrapper {
private:
IFoo *pFoo;
public:
FooWrapper(int type) : pFoo(CreateFooT(type)) { assert(pFoo != nullptr); }
~FooWrapper() { delete pFoo; }
bool functionA() { return pFoo->functionA(); }
template <typename T> bool functionB(T arg)
{
if(pFoo->type() != TypeT<T>())
{
assert(pFoo->type() == TypeT<T>());
return false;
}
return static_cast<typename FooT<T>*>(pFoo)->functionB(arg);
}
// fun stuff:
// (const pendants omitted for readability)
bool changeType(int type)
{
delete pFoo;
pFoo = CreateFooT(type);
return pFoo != nullptr;
}
IFoo* Interface() { return pFoo; }
IFoo* operator->() { return pFoo; }
operator IFoo&() { return *pFoo; }
template <typename T> FooT<T> *InterfaceT()
{
if(pFoo->type() != TypeT<T>())
{
assert(pFoo->type() == TypeT<T>());
return nullptr;
}
return static_cast<typename FooT<T>*>(pFoo);
}
};
int main(int argc, char *argv[])
{
FooWrapper w1(TypeT<bool>());
FooWrapper w2(TypeT<double>());
w1.functionA(); // ok
w2.functionA(); // ok
w1.functionB(true); // ok
w1.functionB(0.5); // runtime error!
w2.functionB(true); // runtime error!
w2.functionB(0.5); // ok
// fun stuff
w2.changeType(TypeT<bool>()); // older changes will be lost
w2.functionB(true); // -> now ok
w1.Interface()->functionA();
w1->functionA();
IFoo &iref = w1;
iref.functionA();
FooT<bool> *ref = w1.InterfaceT<bool>();
ref->functionB(true);
return 0;
}
It is of course your responsibility to call the functions with the correct types, but you can easily add some error handling.
Is there some library that allows me to easily and conveniently create Object-Oriented callbacks in c++?
the language Eiffel for example has the concept of "agents" which more or less work like this:
class Foo{
public:
Bar* bar;
Foo(){
bar = new Bar();
bar->publisher.extend(agent say(?,"Hi from Foo!", ?));
bar->invokeCallback();
}
say(string strA, string strB, int number){
print(strA + " " + strB + " " + number.out);
}
}
class Bar{
public:
ActionSequence<string, int> publisher;
Bar(){}
invokeCallback(){
publisher.call("Hi from Bar!", 3);
}
}
output will be:
Hi from Bar! 3 Hi from Foo!
So - the agent allows to to capsule a memberfunction into an object, give it along some predefined calling parameters (Hi from Foo), specify the open parameters (?), and pass it to some other object which can then invoke it later.
Since c++ doesn't allow to create function pointers on non-static member functions, it seems not that trivial to implement something as easy to use in c++. i found some articles with google on object oriented callbacks in c++, however, actually i'm looking for some library or header files i simply can import which allow me to use some similarily elegant syntax.
Anyone has some tips for me?
Thanks!
The most OO way to use Callbacks in C++ is to call a function of an interface and then pass an implementation of that interface.
#include <iostream>
class Interface
{
public:
virtual void callback() = 0;
};
class Impl : public Interface
{
public:
virtual void callback() { std::cout << "Hi from Impl\n"; }
};
class User
{
public:
User(Interface& newCallback) : myCallback(newCallback) { }
void DoSomething() { myCallback.callback(); }
private:
Interface& myCallback;
};
int main()
{
Impl cb;
User user(cb);
user.DoSomething();
}
People typically use one of several patterns:
Inheritance. That is, you define an abstract class which contains the callback. Then you take a pointer/reference to it. That means that anyone can inherit and provide this callback.
class Foo {
virtual void MyCallback(...) = 0;
virtual ~Foo();
};
class Base {
std::auto_ptr<Foo> ptr;
void something(...) {
ptr->MyCallback(...);
}
Base& SetCallback(Foo* newfoo) { ptr = newfoo; return *this; }
Foo* GetCallback() { return ptr; }
};
Inheritance again. That is, your root class is abstract, and the user inherits from it and defines the callbacks, rather than having a concrete class and dedicated callback objects.
class Foo {
virtual void MyCallback(...) = 0;
...
};
class RealFoo : Foo {
virtual void MyCallback(...) { ... }
};
Even more inheritance- static. This way, you can use templates to change the behaviour of an object. It's similar to the second option but works at compile time instead of at run time, which can yield various benefits and downsides, depending on the context.
template<typename T> class Foo {
void MyCallback(...) {
T::MyCallback(...);
}
};
class RealFoo : Foo<RealFoo> {
void MyCallback(...) {
...
}
};
You can take and use member function pointers or regular function pointers
class Foo {
void (*callback)(...);
void something(...) { callback(...); }
Foo& SetCallback( void(*newcallback)(...) ) { callback = newcallback; return *this; }
void (*)(...) GetCallback() { return callback; }
};
There are function objects- they overload operator(). You will want to use or write a functional wrapper- currently provided in std::/boost:: function, but I'll also demonstrate a simple one here. It's similar to the first concept, but hides the implementation and accepts a vast array of other solutions. I personally normally use this as my callback method of choice.
class Foo {
virtual ... Call(...) = 0;
virtual ~Foo();
};
class Base {
std::auto_ptr<Foo> callback;
template<typename T> Base& SetCallback(T t) {
struct NewFoo : Foo {
T t;
NewFoo(T newt) : t(newt) {}
... Call(...) { return t(...); }
};
callback = new NewFoo<T>(t);
return this;
}
Foo* GetCallback() { return callback; }
void dosomething() { callback->Call(...); }
};
The right solution mainly depends on the context. If you need to expose a C-style API then function pointers is the only way to go (remember void* for user arguments). If you need to vary at runtime (for example, exposing code in a precompiled library) then static inheritance can't be used here.
Just a quick note: I hand whipped up that code, so it won't be perfect (like access modifiers for functions, etc) and may have a couple of bugs in. It's an example.
C++ allows function pointers on member objects.
See here for more details.
You can also use boost.signals or boost.signals2 (depanding if your program is multithreaded or not).
There are various libraries that let you do that. Check out boost::function.
Or try your own simple implementation:
template <typename ClassType, typename Result>
class Functor
{
typedef typename Result (ClassType::*FunctionType)();
ClassType* obj;
FunctionType fn;
public:
Functor(ClassType& object, FunctionType method): obj(&object), fn(method) {}
Result Invoke()
{
return (*obj.*fn)();
}
Result operator()()
{
return Invoke();
}
};
Usage:
class A
{
int value;
public:
A(int v): value(v) {}
int getValue() { return value; }
};
int main()
{
A a(2);
Functor<A, int> fn(a, &A::getValue);
cout << fn();
}
Joining the idea of functors - use std::tr1::function and boost::bind to build the arguments into it before registering it.
There are many possibilities in C++, the issue generally being one of syntax.
You can use pointer to functions when you don't require state, but the syntax is really horrid. This can be combined with boost::bind for an even more... interesting... syntax (*)
I correct your false assumption, it is indeed feasible to have pointer to a member function, the syntax is just so awkward you'll run away (*)
You can use Functor objects, basically a Functor is an object which overloads the () operator, for example void Functor::operator()(int a) const;, because it's an object it has state and may derive from a common interface
You can simply create your own hierarchy, with a nicer name for the callback function if you don't want to go the operator overloading road
Finally, you can take advantage of C++0x facilities: std::function + the lambda functions are truly awesome when it comes to expressiveness.
I would appreciate a review on lambda syntax ;)
Foo foo;
std::function<void(std::string const&,int)> func =
[&foo](std::string const& s, int i) {
return foo.say(s,"Hi from Foo",i);
};
func("Hi from Bar", 2);
func("Hi from FooBar", 3);
Of course, func is only viable while foo is viable (scope issue), you could copy foo using [=foo] to indicate pass by value instead of pass by reference.
(*) Mandatory Tutorial on Function Pointers
Is it possible in C++ to have a member function that is both static and virtual? Apparently, there isn't a straightforward way to do it (static virtual member(); is a compile error), but is there at least a way to achieve the same effect?
I.E:
struct Object
{
struct TypeInformation;
static virtual const TypeInformation &GetTypeInformation() const;
};
struct SomeObject : public Object
{
static virtual const TypeInformation &GetTypeInformation() const;
};
It makes sense to use GetTypeInformation() both on an instance (object->GetTypeInformation()) and on a class (SomeObject::GetTypeInformation()), which can be useful for comparisons and vital for templates.
The only ways I can think of involves writing two functions / a function and a constant, per class, or use macros.
Any other solutions?
No, there's no way to do it, since what would happen when you called Object::GetTypeInformation()? It can't know which derived class version to call since there's no object associated with it.
You'll have to make it a non-static virtual function to work properly; if you also want to be able to call a specific derived class's version non-virtually without an object instance, you'll have to provide a second redunduant static non-virtual version as well.
Many say it is not possible, I would go one step further and say it is not meaningfull.
A static member is something that does not relate to any instance, only to the class.
A virtual member is something that does not relate directly to any class, only to an instance.
So a static virtual member would be something that does not relate to any instance or any class.
I ran into this problem the other day: I had some classes full of static methods but I wanted to use inheritance and virtual methods and reduce code repetition. My solution was:
Instead of using static methods, use a singleton with virtual methods.
In other words, each class should contain a static method that you call to get a pointer to a single, shared instance of the class. You can make the true constructors private or protected so that outside code can't misuse it by creating additional instances.
In practice, using a singleton is a lot like using static methods except that you can take advantage of inheritance and virtual methods.
While Alsk has already given a pretty detailed answer, I'd like to add an alternative, since I think his enhanced implementation is overcomplicated.
We start with an abstract base class, that provides the interface for all the object types:
class Object
{
public:
virtual char* GetClassName() = 0;
};
Now we need an actual implementation. But to avoid having to write both the static and the virtual methods, we will have our actual object classes inherit the virtual methods. This does obviously only work, if the base class knows how to access the static member function. So we need to use a template and pass the actual objects class name to it:
template<class ObjectType>
class ObjectImpl : public Object
{
public:
virtual char* GetClassName()
{
return ObjectType::GetClassNameStatic();
}
};
Finally we need to implement our real object(s). Here we only need to implement the static member function, the virtual member functions will be inherited from the ObjectImpl template class, instantiated with the name of the derived class, so it will access it's static members.
class MyObject : public ObjectImpl<MyObject>
{
public:
static char* GetClassNameStatic()
{
return "MyObject";
}
};
class YourObject : public ObjectImpl<YourObject>
{
public:
static char* GetClassNameStatic()
{
return "YourObject";
}
};
Let's add some code to test:
char* GetObjectClassName(Object* object)
{
return object->GetClassName();
}
int main()
{
MyObject myObject;
YourObject yourObject;
printf("%s\n", MyObject::GetClassNameStatic());
printf("%s\n", myObject.GetClassName());
printf("%s\n", GetObjectClassName(&myObject));
printf("%s\n", YourObject::GetClassNameStatic());
printf("%s\n", yourObject.GetClassName());
printf("%s\n", GetObjectClassName(&yourObject));
return 0;
}
Addendum (Jan 12th 2019):
Instead of using the GetClassNameStatic() function, you can also define the the class name as a static member, even "inline", which IIRC works since C++11 (don't get scared by all the modifiers :)):
class MyObject : public ObjectImpl<MyObject>
{
public:
// Access this from the template class as `ObjectType::s_ClassName`
static inline const char* const s_ClassName = "MyObject";
// ...
};
It is possible!
But what exactly is possible, let's narrow down. People often want some kind of "static virtual function" because of duplication of code needed for being able to call the same function through static call "SomeDerivedClass::myfunction()" and polymorphic call "base_class_pointer->myfunction()". "Legal" method for allowing such functionality is duplication of function definitions:
class Object
{
public:
static string getTypeInformationStatic() { return "base class";}
virtual string getTypeInformation() { return getTypeInformationStatic(); }
};
class Foo: public Object
{
public:
static string getTypeInformationStatic() { return "derived class";}
virtual string getTypeInformation() { return getTypeInformationStatic(); }
};
What if base class has a great number of static functions and derived class has to override every of them and one forgot to provide a duplicating definition for virtual function. Right, we'll get some strange error during runtime which is hard to track down. Cause duplication of code is a bad thing. The following tries to resolve this problem (and I want to tell beforehand that it is completely type-safe and doesn't contain any black magic like typeid's or dynamic_cast's :)
So, we want to provide only one definition of getTypeInformation() per derived class and it is obvious that it has to be a definition of static function because it is not possible to call "SomeDerivedClass::getTypeInformation()" if getTypeInformation() is virtual. How can we call static function of derived class through pointer to base class? It is not possible with vtable because vtable stores pointers only to virtual functions and since we decided not to use virtual functions, we cannot modify vtable for our benefit. Then, to be able to access static function for derived class through pointer to base class we have to store somehow the type of an object within its base class. One approach is to make base class templatized using "curiously recurring template pattern" but it is not appropriate here and we'll use a technique called "type erasure":
class TypeKeeper
{
public:
virtual string getTypeInformation() = 0;
};
template<class T>
class TypeKeeperImpl: public TypeKeeper
{
public:
virtual string getTypeInformation() { return T::getTypeInformationStatic(); }
};
Now we can store the type of an object within base class "Object" with a variable "keeper":
class Object
{
public:
Object(){}
boost::scoped_ptr<TypeKeeper> keeper;
//not virtual
string getTypeInformation() const
{ return keeper? keeper->getTypeInformation(): string("base class"); }
};
In a derived class keeper must be initialized during construction:
class Foo: public Object
{
public:
Foo() { keeper.reset(new TypeKeeperImpl<Foo>()); }
//note the name of the function
static string getTypeInformationStatic()
{ return "class for proving static virtual functions concept"; }
};
Let's add syntactic sugar:
template<class T>
void override_static_functions(T* t)
{ t->keeper.reset(new TypeKeeperImpl<T>()); }
#define OVERRIDE_STATIC_FUNCTIONS override_static_functions(this)
Now declarations of descendants look like:
class Foo: public Object
{
public:
Foo() { OVERRIDE_STATIC_FUNCTIONS; }
static string getTypeInformationStatic()
{ return "class for proving static virtual functions concept"; }
};
class Bar: public Foo
{
public:
Bar() { OVERRIDE_STATIC_FUNCTIONS; }
static string getTypeInformationStatic()
{ return "another class for the same reason"; }
};
usage:
Object* obj = new Foo();
cout << obj->getTypeInformation() << endl; //calls Foo::getTypeInformationStatic()
obj = new Bar();
cout << obj->getTypeInformation() << endl; //calls Bar::getTypeInformationStatic()
Foo* foo = new Bar();
cout << foo->getTypeInformation() << endl; //calls Bar::getTypeInformationStatic()
Foo::getTypeInformation(); //compile-time error
Foo::getTypeInformationStatic(); //calls Foo::getTypeInformationStatic()
Bar::getTypeInformationStatic(); //calls Bar::getTypeInformationStatic()
Advantages:
less duplication of code (but we
have to call
OVERRIDE_STATIC_FUNCTIONS in every
constructor)
Disadvantages:
OVERRIDE_STATIC_FUNCTIONS in every
constructor
memory and performance
overhead
increased complexity
Open issues:
1) there are different names for static and virtual functions
how to solve ambiguity here?
class Foo
{
public:
static void f(bool f=true) { cout << "static";}
virtual void f() { cout << "virtual";}
};
//somewhere
Foo::f(); //calls static f(), no ambiguity
ptr_to_foo->f(); //ambiguity
2) how to implicitly call OVERRIDE_STATIC_FUNCTIONS inside every constructor?
It is possible. Make two functions: static and virtual
struct Object{
struct TypeInformation;
static const TypeInformation &GetTypeInformationStatic() const
{
return GetTypeInformationMain1();
}
virtual const TypeInformation &GetTypeInformation() const
{
return GetTypeInformationMain1();
}
protected:
static const TypeInformation &GetTypeInformationMain1(); // Main function
};
struct SomeObject : public Object {
static const TypeInformation &GetTypeInformationStatic() const
{
return GetTypeInformationMain2();
}
virtual const TypeInformation &GetTypeInformation() const
{
return GetTypeInformationMain2();
}
protected:
static const TypeInformation &GetTypeInformationMain2(); // Main function
};
No, this is not possible, because static member functions lack a this pointer. And static members (both functions and variables) are not really class members per-se. They just happen to be invoked by ClassName::member, and adhere to the class access specifiers. Their storage is defined somewhere outside the class; storage is not created each time you instantiated an object of the class. Pointers to class members are special in semantics and syntax. A pointer to a static member is a normal pointer in all regards.
virtual functions in a class needs the this pointer, and is very coupled to the class, hence they can't be static.
It's not possible, but that's just because an omission. It isn't something that "doesn't make sense" as a lot of people seem to claim. To be clear, I'm talking about something like this:
struct Base {
static virtual void sayMyName() {
cout << "Base\n";
}
};
struct Derived : public Base {
static void sayMyName() override {
cout << "Derived\n";
}
};
void foo(Base *b) {
b->sayMyName();
Derived::sayMyName(); // Also would work.
}
This is 100% something that could be implemented (it just hasn't), and I'd argue something that is useful.
Consider how normal virtual functions work. Remove the statics and add in some other stuff and we have:
struct Base {
virtual void sayMyName() {
cout << "Base\n";
}
virtual void foo() {
}
int somedata;
};
struct Derived : public Base {
void sayMyName() override {
cout << "Derived\n";
}
};
void foo(Base *b) {
b->sayMyName();
}
This works fine and basically what happens is the compiler makes two tables, called VTables, and assigns indices to the virtual functions like this
enum Base_Virtual_Functions {
sayMyName = 0;
foo = 1;
};
using VTable = void*[];
const VTable Base_VTable = {
&Base::sayMyName,
&Base::foo
};
const VTable Derived_VTable = {
&Derived::sayMyName,
&Base::foo
};
Next each class with virtual functions is augmented with another field that points to its VTable, so the compiler basically changes them to be like this:
struct Base {
VTable* vtable;
virtual void sayMyName() {
cout << "Base\n";
}
virtual void foo() {
}
int somedata;
};
struct Derived : public Base {
VTable* vtable;
void sayMyName() override {
cout << "Derived\n";
}
};
Then what actually happens when you call b->sayMyName()? Basically this:
b->vtable[Base_Virtual_Functions::sayMyName](b);
(The first parameter becomes this.)
Ok fine, so how would it work with static virtual functions? Well what's the difference between static and non-static member functions? The only difference is that the latter get a this pointer.
We can do exactly the same with static virtual functions - just remove the this pointer.
b->vtable[Base_Virtual_Functions::sayMyName]();
This could then support both syntaxes:
b->sayMyName(); // Prints "Base" or "Derived"...
Base::sayMyName(); // Always prints "Base".
So ignore all the naysayers. It does make sense. Why isn't it supported then? I think it's because it has very little benefit and could even be a little confusing.
The only technical advantage over a normal virtual function is that you don't need to pass this to the function but I don't think that would make any measurable difference to performance.
It does mean you don't have a separate static and non-static function for cases when you have an instance, and when you don't have an instance, but also it might be confusing that it's only really "virtual" when you use the instance call.
Well , quite a late answer but it is possible using the curiously recurring template pattern. This wikipedia article has the info you need and also the example under static polymorphism is what you are asked for.
This question is over a decade old, but it looks like it gets a good amount of traffic, so I wanted to post an alternative using modern C++ features that I haven't seen anywhere else.
This solution uses CRTP and SFINAE to perform static dispatching. That, in itself, is nothing new, but all such implementations I've found lack strict signature checking for "overrides." This implementation requires that the "overriding" method signature exactly matches that of the "overridden" method. This behavior more closely resembles that of virtual functions, while also allowing us to effectively overload and "override" a static method.
Note that I put override in quotes because, strictly speaking, we're not technically overriding anything. Instead, we're calling a dispatch method X with signature Y that forwards all of its arguments to T::X, where T is to the first type among a list of types such that T::X exists with signature Y. This list of types considered for dispatching can be anything, but generally would include a default implementation class and the derived class.
Implementation
#include <experimental/type_traits>
template <template <class...> class Op, class... Types>
struct dispatcher;
template <template <class...> class Op, class T>
struct dispatcher<Op, T> : std::experimental::detected_t<Op, T> {};
template <template <class...> class Op, class T, class... Types>
struct dispatcher<Op, T, Types...>
: std::experimental::detected_or_t<
typename dispatcher<Op, Types...>::type, Op, T> {};
// Helper to convert a signature to a function pointer
template <class Signature> struct function_ptr;
template <class R, class... Args> struct function_ptr<R(Args...)> {
using type = R (*)(Args...);
};
// Macro to simplify creation of the dispatcher
// NOTE: This macro isn't smart enough to handle creating an overloaded
// dispatcher because both dispatchers will try to use the same
// integral_constant type alias name. If you want to overload, do it
// manually or make a smarter macro that can somehow put the signature in
// the integral_constant type alias name.
#define virtual_static_method(name, signature, ...) \
template <class VSM_T> \
using vsm_##name##_type = std::integral_constant< \
function_ptr<signature>::type, &VSM_T::name>; \
\
template <class... VSM_Args> \
static auto name(VSM_Args&&... args) \
{ \
return dispatcher<vsm_##name##_type, __VA_ARGS__>::value( \
std::forward<VSM_Args>(args)...); \
}
Example Usage
#include <iostream>
template <class T>
struct Base {
// Define the default implementations
struct defaults {
static std::string alpha() { return "Base::alpha"; };
static std::string bravo(int) { return "Base::bravo"; }
};
// Create the dispatchers
virtual_static_method(alpha, std::string(void), T, defaults);
virtual_static_method(bravo, std::string(int), T, defaults);
static void where_are_the_turtles() {
std::cout << alpha() << std::endl; // Derived::alpha
std::cout << bravo(1) << std::endl; // Base::bravo
}
};
struct Derived : Base<Derived> {
// Overrides Base::alpha
static std::string alpha(){ return "Derived::alpha"; }
// Does not override Base::bravo because signatures differ (even though
// int is implicitly convertible to bool)
static std::string bravo(bool){ return "Derived::bravo"; }
};
int main() {
Derived::where_are_the_turtles();
}
I think what you're trying to do can be done through templates. I'm trying to read between the lines here. What you're trying to do is to call a method from some code, where it calls a derived version but the caller doesn't specify which class. Example:
class Foo {
public:
void M() {...}
};
class Bar : public Foo {
public:
void M() {...}
};
void Try()
{
xxx::M();
}
int main()
{
Try();
}
You want Try() to call the Bar version of M without specifying Bar. The way you do that for statics is to use a template. So change it like so:
class Foo {
public:
void M() {...}
};
class Bar : public Foo {
public:
void M() {...}
};
template <class T>
void Try()
{
T::M();
}
int main()
{
Try<Bar>();
}
No, Static member function can't be virtual .since virtual concept is resolved at run time with the help of vptr, and vptr is non static member of a class.due to that static member function can't acess vptr so static member can't be virtual.
No, its not possible, since static members are bound at compile time, while virtual members are bound at runtime.
If your desired use for a virtual static is to be able to define an interface over the static section of a class then there is a solution to your problem using C++20 concept's.
class ExBase { //object properties
public: virtual int do(int) = 0;
};
template <typename T> //type properties
concept ExReq = std::derived_from<T, ExBase> && requires(int i) { //~constexpr bool
{
T::do_static(i) //checks that this compiles
} -> std::same_as<int> //checks the expression type is int
};
class ExImpl : virtual public ExBase { //satisfies ExReq
public: int do(int i) override {return i;} //overrides do in ExBase
public: static int do_static(int i) {return i;} //satisfies ExReq
};
//...
void some_func(ExReq auto o) {o.do(0); decltype(o)::do_static(0);}
(this works the same way on members aswell!)
For more on how concepts work: https://en.cppreference.com/w/cpp/language/constraints
For the standard concepts added in C++20: https://en.cppreference.com/w/cpp/concepts
First, the replies are correct that what the OP is requesting is a contradiction in terms: virtual methods depend on the run-time type of an instance; static functions specifically don't depend on an instance -- just on a type. That said, it makes sense to have static functions return something specific to a type. For example, I had a family of MouseTool classes for the State pattern and I started having each one have a static function returning the keyboard modifier that went with it; I used those static functions in the factory function that made the correct MouseTool instance. That function checked the mouse state against MouseToolA::keyboardModifier(), MouseToolB::keyboardModifier(), etc. and then instantiated the appropriate one. Of course later I wanted to check if the state was right so I wanted write something like "if (keyboardModifier == dynamic_type(*state)::keyboardModifier())" (not real C++ syntax), which is what this question is asking.
So, if you find yourself wanting this, you may want to rething your solution. Still, I understand the desire to have static methods and then call them dynamically based on the dynamic type of an instance. I think the Visitor Pattern can give you what you want. It gives you what you want. It's a bit of extra code, but it could be useful for other visitors.
See: http://en.wikipedia.org/wiki/Visitor_pattern for background.
struct ObjectVisitor;
struct Object
{
struct TypeInformation;
static TypeInformation GetTypeInformation();
virtual void accept(ObjectVisitor& v);
};
struct SomeObject : public Object
{
static TypeInformation GetTypeInformation();
virtual void accept(ObjectVisitor& v) const;
};
struct AnotherObject : public Object
{
static TypeInformation GetTypeInformation();
virtual void accept(ObjectVisitor& v) const;
};
Then for each concrete Object:
void SomeObject::accept(ObjectVisitor& v) const {
v.visit(*this); // The compiler statically picks the visit method based on *this being a const SomeObject&.
}
void AnotherObject::accept(ObjectVisitor& v) const {
v.visit(*this); // Here *this is a const AnotherObject& at compile time.
}
and then define the base visitor:
struct ObjectVisitor {
virtual ~ObjectVisitor() {}
virtual void visit(const SomeObject& o) {} // Or = 0, depending what you feel like.
virtual void visit(const AnotherObject& o) {} // Or = 0, depending what you feel like.
// More virtual void visit() methods for each Object class.
};
Then the concrete visitor that selects the appropriate static function:
struct ObjectVisitorGetTypeInfo {
Object::TypeInformation result;
virtual void visit(const SomeObject& o) {
result = SomeObject::GetTypeInformation();
}
virtual void visit(const AnotherObject& o) {
result = AnotherObject::GetTypeInformation();
}
// Again, an implementation for each concrete Object.
};
finally, use it:
void printInfo(Object& o) {
ObjectVisitorGetTypeInfo getTypeInfo;
Object::TypeInformation info = o.accept(getTypeInfo).result;
std::cout << info << std::endl;
}
Notes:
Constness left as an exercise.
You returned a reference from a static. Unless you have a singleton, that's questionable.
If you want to avoid copy-paste errors where one of your visit methods calls the wrong static function, you could use a templated helper function (which can't itself be virtual) t your visitor with a template like this:
struct ObjectVisitorGetTypeInfo {
Object::TypeInformation result;
virtual void visit(const SomeObject& o) { doVisit(o); }
virtual void visit(const AnotherObject& o) { doVisit(o); }
// Again, an implementation for each concrete Object.
private:
template <typename T>
void doVisit(const T& o) {
result = T::GetTypeInformation();
}
};
With c++ you can use static inheritance with the crt method. For the example, it is used widely on window template atl & wtl.
See https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
To be simple, you have a class that is templated from itself like class myclass : public myancestor. From this point the myancestor class can now call your static T::YourImpl function.
I had a browse through the other answers and none of them seem to mention virtual function tables (vtable), which explains why this is not possible.
A static function inside a C++ class compiles to something which is effectively the same as any other function in a regular namespace.
In other words, when you declare a function static you are using the class name as a namespace rather than an object (which has an instance, with some associated data).
Let's quickly look at this...
// This example is the same as the example below
class ExampleClass
{
static void exampleFunction();
int someData;
};
// This example is the same as the example above
namespace ExampleClass
{
void exampleFunction();
// Doesn't work quite the same. Each instance of a class
// has independent data. Here the data is global.
int someData;
}
With that out of the way, and an understanding of what a static member function really is, we can now consider vtables.
If you declare any virtual function in a class, then the compiler creates a block of data which (usually) precedes other data members. This block of data contains runtime information which tells the program at runtime where in memory it needs to jump to in order to execute the correct (virtual) function for each instance of a class which might be created during runtime.
The important point here is "block of data". In order for that block of data to exist, it has to be stored as part of an instance of an object (class). If your function is static, then we already said it uses the name of the class as a namespace. There is no object associated with that function call.
To add slightly more detail: A static function does not have an implicit this pointer, which points to the memory where the object lives. Because it doesn't have that, you can't jump to a place in memory and find the vtable for that object. So you can't do virtual function dispatch.
I'm not an expert in compiler engineering by any means, but understanding things at least to this level of detail is helpful, and (hopefully?) makes it easy to understand why (at least in C++) static virtual does not make sense, and cannot be translated into something sensible by the compiler.
Maybe you can try my solution below:
class Base {
public:
Base(void);
virtual ~Base(void);
public:
virtual void MyVirtualFun(void) = 0;
static void MyStaticFun(void) { assert( mSelf != NULL); mSelf->MyVirtualFun(); }
private:
static Base* mSelf;
};
Base::mSelf = NULL;
Base::Base(void) {
mSelf = this;
}
Base::~Base(void) {
// please never delete mSelf or reset the Value of mSelf in any deconstructors
}
class DerivedClass : public Base {
public:
DerivedClass(void) : Base() {}
~DerivedClass(void){}
public:
virtual void MyVirtualFun(void) { cout<<"Hello, it is DerivedClass!"<<endl; }
};
int main() {
DerivedClass testCls;
testCls.MyStaticFun(); //correct way to invoke this kind of static fun
DerivedClass::MyStaticFun(); //wrong way
return 0;
}
Like others have said, there are 2 important pieces of information:
there is no this pointer when making a static function call and
the this pointer points to the structure where the virtual table, or thunk, are used to look up which runtime method to call.
A static function is determined at compile time.
I showed this code example in C++ static members in class; it shows that you can call a static method given a null pointer:
struct Foo
{
static int boo() { return 2; }
};
int _tmain(int argc, _TCHAR* argv[])
{
Foo* pFoo = NULL;
int b = pFoo->boo(); // b will now have the value 2
return 0;
}