Would someone please explain to me the bold parts?
I didn't get how come *__vptr which is in the Base portion of the class and dPtr has access to this pointer CAN all of a sudden point to the D1 virtual table instead of the Base virtual table!
I have read some articles, watched some sources and still confused.
class Base
{
public:
virtual void function1() {};
virtual void function2() {};
};
class D1: public Base
{
public:
virtual void function1() {};
};
class D2: public Base
{
public:
virtual void function2() {};
};
int main()
{
D1 d1;
Base *dPtr = &d1;
return 0;
}
Note that because dPtr is a base pointer, it only points to the Base portion of d1. However, also note that *__vptr is in the Base portion of the class, so dPtr has access to this pointer. Finally, note that dPtr->__vptr points to the D1 virtual table! Consequently, even though dPtr is of type Base, it still has access to D1’s virtual table (through __vptr).
Source: https://www.learncpp.com/cpp-tutorial/125-the-virtual-table/comment-page-6/#comment-484189
To understand c++ you need to understand that the implementation of C++ is not the definition of C++.
C++ is defined by the behavior of an abstract machine. This abstract machine's behavior is defined by the standard, and a compliant C++ compiler must compile programs to run as-if they ran on that abstract machine.
The rules of what that abstract machine does are inspired and based off of real computers and real implementations of C++ and C programs.
So when you talk about "virtual function tables", you are talking about one common implementation of what C++ does with virtual methods. That common implementation doesn't define how C++ acts, and mixing the two up can cause problems.
That being said, C++'s virtual methods where based off of doing basically the exact same thing in C. It can help to sketch out how virtual methods and inheritance would work in C++ if you re-implemented it. (this has practical use, because doing so lets you make a custom object model, and custom object models let you do certain things more efficiently that the C++ object model would).
struct Bob_vtable {
void(*print)(Bob const*) = 0;
};
struct Bob {
Bob_vtable const* vtable = 0;
int x = 0;
// glue code to dispatch to vtable:
void print() const {
return vtable->print(this);
}
// implementation of Bob::print:
static void print_impl( Bob const* self ) {
std::cout << self->x;
}
// vtable helpers:
static Bob_vtable make_vtable() {
return { &Bob::print_impl };
}
static Bob_vtable const* get_vtable() {
static const Bob_vtable retval = make_vtable();
return &retval;
}
Bob():vtable(get_vtable()) {}
};
here is a really simple, no inheritance, implementation of a class Bob with a single virtual method print. It roughly corresponds to:
class Bob {
public:
int x = 0;
virtual void print() const { std::cout << x; }
};
you can see why it is nice to have all of this glue code written for you.
When you do this:
class Alice : public Bob {
public:
int y = 0;
void print() const override { std::cout << x << "," << y; }
};
the "manual implementation" would look someting like:
struct Alice : Bob {
int y = 0;
// no print glue code needed(!)
// implementation of Alice::print:
static void print_impl( Bob const* bobself ) {
Alice const* self = static_cast<Alice const*>(bobself);
std::cout << self->x << "," << self->y;
}
static Bob_vtable make_vtable() {
Bob_vtable bob_version = Bob::make_vtable();
bob_version.print = &Alice::print_impl;
return bob_version;
}
static Bob_vtable const* get_vtable() {
static const Bob_vtable retval = make_vtable();
return &retval;
}
Alice():Bob() {
// after constructing Bob, replace the vtable with ours:
vtable = get_vtable();
}
};
and there you have it.
Take a look at what happens here:
Alice a;
a.print(std::cout);
now, a.print actually calls Bob::print, because Alice has no print method.
Bob.print does this:
void print() const {
return vtable->print(this);
}
it grabs the vtable pointer of this object instance, and calls the print function in it.
What is the vtable pointer of an object of type Alice? Look at the Alice constructor.
First it default-constructs Bob (which sets vtable to point at Bob's vtable), but then it does this:
vtable = get_vtable();
this call to get_vtable calls Alice::get_vtable:
static const Bob_vtable retval = make_vtable();
return &retval;
which in turn calls Alice::make_vtable:
Bob_vtable bob_version = Bob::make_vtable();
bob_version.print = &Alice::print_impl;
return bob_version;
which first calls Bob's make_vtable, then replaces .print with the Alice::print_impl.
So Bob::print calls vtable->print(this), which is Alice::print_impl(this), which does:
Alice const* self = static_cast<Alice const*>(bobself);
std::cout << self->x << "," << self->y;
While this is a Bob const* at this point, it is pointing at an Alice object, so that static_cast is valid.
So we print x and y from Alice.
Now, here Alice's vtable type is Bob_vtable because she didn't add any new methods. If she added new methods, she would have an Alice_vtable that inherited from Bob_vtable, and would have to static_cast<Alice_vtable const*>(vtable) to access them.
This isn't quite exactly what c++ does "under the hood", but it is about as logically identical as I can write "off the cuff". There are a myriad of different details, like the calling convention of the functions in the vtable is different, and the format of the vtable in memory doesn't match that, etc.
Now, in the 'manual implementation' I did use inheritance. So that isn't C; but the inheritance in the 'manual implementation' is not doing anything object oriented.
struct A {int x;};
struct B:A{int y;};
is just doing
struct A {
int x;
};
struct B {
A base;
int y;
};
with a bit of syntactic glitter on top.
The "manual implementation" is nearly 1:1 on how you would implement this (and people do) in c. You would move the methods out of the class, call them void Bob_print(Bob const*) instead of void Bob::print() const. And you'd use struct Alice { Bob base; int y; } instead of struct Alice:Bob{ int y; };. But the difference is almost completely syntax, not anything else.
When c++ was originally developed, OO-based C existed, and one of C++'s first goals was to be able to write C-with-classes without having to write all of the above boilerplate.
Now, C++'s object model does not require the above implementation. In fact, relying on the above implementation can result in ill-formed programs or undefined behavior. But understanding one possible way to implement C++'s object model has some use; plus, once you know how to implement C++'s object model, you can use different object models in C++.
Note that in modern C++, I'd use a lot more templates above to remove some of the boilerplate. As a practical use, I've used similar techniques to implement augmented std::any's with duck-typed virtual methods.
The result is you can get this syntax:
auto print = poly_method<void(Self const*, std::ostream&)>{
[](auto const*self, std::ostream& os){ os << *self; }
};
poly_any<&print> x = 7;
x->*print(std::cout);
(don't try this at home).
Essentially I'm trying to work around the problem of not being able to store derived types as a derived type in a (value) array of a base type. I have multiple classes that store one to three ints but have to have very different sets of functions. I'd use an array of pointers but the entire array is traversed forwards, then backwards constantly, mostly linearly, so keeping it all together in memory is preferable. I could create multiple arrays, one for each type and then an array of pointers to each of those, but that would get pretty clumsy fast and really wouldn't be the same as each element packed neatly between the one preceding it and the one proceeding it in order of access at runtime.
So what I'm thinking is that I make a POD struct with three ints and a pointer and fill an array with those, then use that pointer to access polymorphic functions. It would end up something along these lines: (forgive the poor coding here, I'm just trying to convey the concept)
class A {
int aa( &foo f ) { return 1; }
int dd() { return 9; }
};
class B : A {
int aa( &foo f ) { return f.b; }
};
class C : A {
int aa( &foo f ) { return cc() + f.c - f.a; }
int cc() { return 4; }
};
class D : B {
int dd() { return 7; }
};
struct foo{ int a, b, c; A* ptr; };
const A AA = A(); const B BB = B(); const C CC = C(); const D DD = D();
foo[100] foos;
init() {
foo[0] = foo{ 1, 2, 3, &BB };
// etc fill foos with various foo elements
}
bar(){
for ( int i = 0; i < 100; ++i ){
print foos[i].ptr.aa( &foos[i] );
print foos[i].ptr.dd();
}
}
main(){
init();
while(true)
bar();
}
I'm just wondering if this is the best way to go about what I want to achieve or if there's a better solution? Ideally I'd just point to a class rather than an instance of a class but I don't think I can really do that... ideally I'd store them in an array as multiple derived types but for obvious reasons that's not going to fly.
What you are looking for are virtual functions.
In the bellow example :
class A
{
virtual void foo(){printf("A is called");};
}
class B : public A
{
void foo(){printf("B is called");};
}
...
A* ptr = new B();
ptr->foo();
Will produce "B is called" .
If you don't want to use virtual functions (to save memory for example), you can use dynamic cast , but this will lead to significant performance loss.
Please not that you need to have at least 1 virtual function to perform dynamic cast.
In the example bellow :
class A {...}
class B : public A {...}
class C : public A {...}
A* ptr1 = new C();
B* ptr2 = dynamic_cast<B*>(ptr1);
C* ptr3 = dynamic_cast<C*>(ptr1);
ptr2 will be null, and ptr3 will have a value.
So you can make the following (very wrong) construct :
if (ptr2)
{
ptr2->bb();
} else if (ptr3)
{
ptr3->cc();
}
Finally, you can get rid of dynamic casting by having your own typing mechanism and then just C cast to the correct class.
You need polymorphism. In your example all the classes have standard methods. You need to make them virtual, so the polymorphism can be applied.
class A {
virtual int aa( foo& f )const { return 1; }
virtual int dd()const { return 9; }
};
class B : A {
virtual int aa( foo& f )const { return f.b; }
};
class C : A {
virtual int aa( foo& f )const { return cc() + f.c - f.a; }
int cc()const { return 4; }// this doesn't need to be virtual because is not in the base class A
};
class D : B {
virtual int dd()const { return 7; }
};
Here is some information on this topic: http://www.cplusplus.com/doc/tutorial/polymorphism/. There is some information on how to use pointers as well.
I would suggest to look at smart pointers: http://www.cplusplus.com/reference/memory/shared_ptr/?kw=shared_ptr
Another topic you should look at is constness: search for "constness c++" (cannot post more then 2 links)
struct foo{ int a, b, c;const A* ptr; }; // const A* instead of A*
... I'm trying to work around the problem of not being able to store derived types as a derived type in a (value) array of a base type.
You can store derived types, as values, in an array - you just can't store them as instances of the base type.
A union of your concrete leaf types is almost what you want, but there's no way to figure out which member of the union is live, or to use polymorphic dispatch.
A discriminated union is one which tells you which member is live, but doesn't directly help with the dispatch.
Boost.Variant is a specific discriminated union which provides a clean mechanism for polymorphic dispatch - not using virtual, but using a visitor with overloads for each concrete stored type. In this case, you don't even need the stored types to be related to a common abstract base - they can be entirely unrelated. Look for apply_visitor in the tutorial for details.
Suppose I have class Base and Derived : public Base.
I have constructed a shared memory segment using boost::interprocess library. Is it possible to have code similar to this:
Base* b = new Derived();
write(b); //one app writes
Base* b2 = read(b); //second app reads
//b equals b2 (bitwise, not the ptr location)
The problems I see here is for instance that the required space for a derived class of Base is unknown (so how much shmem to allocate?)
Q: how to pass objects via pointers between applications?
Just read its documentation
In particular:
Virtuality forbidden
The virtual table pointer and the virtual table are in the address
space of the process that constructs the object, so if we place a
class with a virtual function or virtual base class, the virtual
pointer placed in shared memory will be invalid for other processes
and they will crash.
This problem is very difficult to solve, since each process needs a
different virtual table pointer and the object that contains that
pointer is shared across many processes. Even if we map the mapped
region in the same address in every process, the virtual table can be
in a different address in every process. To enable virtual functions
for objects shared between processes, deep compiler changes are needed
and virtual functions would suffer a performance hit. That's why
Boost.Interprocess does not have any plan to support virtual function
and virtual inheritance in mapped regions shared between processes.
Shared memory originally only allows POD structures (at heart, they may have constructors/copy/etc...).
Boost.Interprocess raises the bar by emulating pointers semantics on top of offsets into the shared memory segment.
However, a virtual pointer is not a pointer to pure data, it's a pointer to code sections, and that is where things get complicated because code sections are not necessarily mapped to the same address from one process to another (even if they were launched from the same binary).
So... no, virtual pointers-polymorphic objects cannot be stored in shared memory.
However, just because many C++ implementations chose to use a virtual-pointer mechanism does not mean that this is the only way to have polymorphic behavior. For example, in LLVM and Clang they build on their closed hierarchies to get polymorphism without virtual pointers (and RTTI) so as to lower memory requirements. Those objects could, effectively, be stored in shared memory.
So, how to get polymorphism compatible with shared memory: we need not to store pointers to tables/functions, however we can store indexes.
Example of the idea, but could probably be refined.
/// In header
#include <cassert>
#include <vector>
template <class, size_t> class BaseT;
class Base {
template <class, size_t> friend class BaseT;
public:
int get() const; // -> Implement: 'int getImpl() const' in Derived
void set(int i); // = 0 -> Implement: 'void setImpl(int i)' in Derived
private:
struct VTable {
typedef int (*Getter)(void const*);
typedef void (*Setter)(void*, int);
VTable(): _get(0), _set(0) {}
Getter _get;
Setter _set;
};
static std::vector<VTable>& VT(); // defined in .cpp
explicit Base(size_t v): _v(v) {}
size_t _v;
}; // class Base
template <class Derived, size_t Index>
class BaseT: public Base {
public:
BaseT(): Base(Index) {
static bool const _ = Register();
(void)_;
}
// Provide default implementation of getImpl
int getImpl() const { return 0; }
// No default implementation setImpl
private:
static int Get(void const* b) {
Derived const* d = static_cast<Derived const*>(b);
return d->getImpl();
}
static void Set(void* b, int i) {
Derived* d = static_cast<Derived*>(b);
d->setImpl(i);
}
static bool Register() {
typedef Base::VTable VTable;
std::vector<VTable>& vt = Base::VT();
if (vt.size() <= Index) {
vt.insert(vt.end(), Index - vt.size() + 1, VTable());
} else {
assert(vt[Index]._get == 0 && "Already registered VTable!");
}
vt[Index]._get = &Get;
vt[Index]._set = &Set;
}
}; // class BaseT
/// In source
std::vector<VTable>& Base::VT() {
static std::vector<VTable> V;
return V;
} // Base::VT
int Base::get() const {
return VT()[_v]._get(this);
} // Base::get
void Base::set(int i) {
return VT()[_v]._set(this, i);
} // Base::set
Okay... I guess that now you appreciate the compiler's magic...
Regarding the usage, it's fortunately much simpler:
/// Another header
#include <Base.h>
// 4 must be unique within the hierarchy
class Derived: public BaseT<Derived, 4> {
template <class, size_t> friend class BaseT;
public:
Derived(): _i(0) {}
private:
int getImpl() const { return _i; }
void setImpl(int i) { _i = i; }
int _i;
}; // class Derived
In action at ideone.
I believe you are looking at serialization of objects. Have a look at http://www.boost.org/doc/libs/1_51_0/libs/serialization/doc/index.html
A few ways you can do is:
1. serialize your C++ class
2. send data to another app
3. deserialize into C++ class.
//From the example above , I have removed VTable
// I also removed static variables as per boost::interprocess
// static variable don't work with shared memory, and also I did not see
// any advantage in actually builting a VTable for all derived classes
#include <vector>
#include <boost/bind.hpp>
#include <boost/function.hpp>
template <class> class BaseT;
class Base {
template <class> friend class BaseT;
boost::function< int (void) > _get;
boost::function< void (int) > _set;
public:
int get() {
return _get();
} // -> Implement: 'int get() ' in Derived
void set(int i) {
_set(i);
} // = 0 -> Implement: 'void set(int i)' in Derived
}; // class Base
template <class Derived>
class BaseT : public Base {
public:
BaseT() : Base(), impl(static_cast<Derived *> (this)) {
Base::_get = boost::bind(&BaseT<Derived>::get, this);
Base::_set = boost::bind(&BaseT<Derived>::set, this, _1);
}
int get() {
return impl->get();
}
void set(int i) {
impl->set(i);
}
private:
Derived * impl;
};
//some A implementation of Base
struct A : BaseT<A> {
int get() {
return 101; //testing implementation
}
void set(int i) {
; //implementation goes here
}
};
//some B implementation of Base
struct B : BaseT<B> {
int get() {
return 102; //testing implementation
}
void set(int i) {
; //implementation goes here
}
};
int main() {
BaseT<A> objectA;
BaseT<B> objectB;
Base *a = &objectA;
Base *b = &objectB;
std::cout << a->get() << " returned from A class , "
<< b->get() << " returned from B class " << std::endl;
return 0;
}
//While redefining I changed semantics of constnance in getter,
//and had non- const Derived pointer used for both getter and setter.
//But original simantics can be preserved as following:
int get() const {
//return impl->get();
//this enforces that get has to be const
static_cast<const Derived *> (this)->get() ;
}
When we create an object of a class what does it memory map look like. I am more interested in how the object calls the non virtual member functions. Does the compiler create a table like vtable which is shared between all objects?
class A
{
public:
void f0() {}
int int_in_b1;
};
A * a = new A;
What will be the memory map of a?
You can imagine this code:
struct A {
void f() {}
int int_in_b1;
};
int main() {
A a;
a.f();
return 0;
}
Being transformed into something like:
struct A {
int int_in_b1;
};
void A__f(A* const this) {}
int main() {
A a;
A__f(&a);
return 0;
}
Calling f is straight-forward because it's non-virtual. (And sometimes for virtual calls, the virtual dispatch can be avoided if the dynamic type of the object is known, as it is here.)
A longer example that will either give you an idea about how virtual functions work or terribly confuse you:
struct B {
virtual void foo() { puts(__func__); }
};
struct D : B {
virtual void foo() { puts(__func__); }
};
int main() {
B* a[] = { new B(), new D() };
a[0]->foo();
a[1]->foo();
return 0;
}
Becomes something like:
void B_foo(void) { puts(__func__); }
void D_foo(void) { puts(__func__); }
struct B_VT {
void (*foo)(void);
}
B_vtable = { B_foo },
D_vtable = { D_foo };
typedef struct B {
struct B_VT* vt;
} B;
B* new_B(void) {
B* p = malloc(sizeof(B));
p->vt = &B_vtable;
return p;
}
typedef struct D {
struct B_VT* vt;
} D;
D* new_D(void) {
D* p = malloc(sizeof(D));
p->vt = &D_vtable;
return p;
}
int main() {
B* a[] = {new_B(), new_D()};
a[0]->vt->foo();
a[1]->vt->foo();
return 0;
}
Each object only has one vtable pointer, and you can add many virtual methods to the class without affecting object size. (The vtable grows, but this is stored once per class and is not significant size overhead.) Note that I've simplified many details in this example, but it does work: destructors are not addressed (which should additionally be virtual here), it leaks memory, and the __func__ values will be slightly different (they're generated by the compiler for the current function's name), among others.
Recognize that the C++ language doesn't specify or mandate everything about memory layout for objects. That said, most compilers do it pretty much the same.
In your example, objects of type A require only enough memory to hold an int. Since it has no virtual functions, it needs no vtable. If the f0 member had been declared virtual, then objects of type A would typically start with a pointer to the class A vtable (shared by all objects of type A) followed by the int member.
In turn, the vtable has a pointer to each virtual function, defined, inherited or overridden. Calling a virtual function for an object consists of following the pointer to the vtable from the object, then using a fixed offset into the vtable (determined at compile time for each virtual function) to find the address of the function to call.
functions are not stored based on what class they are in.
usually the compiler will just treat any member function just like any other function except adds an argument for the 'this' pointer. which is automatically passed to the function when you called it based on the address of the object it is called on.
all functions, static, member, or even virtual member are stored in memory in the same way, they are all just functions.
when the compiler builds the code it pretty much hard codes where it goes into memory, then the linker goes through your code and replaces the "call the function with this name" command with "call the function at this hard coded address"
class A
{
public:
void f0() {}
void f1(int x) {int_in_b1 = x; }
int int_in_b1;
};
A *a = new A();
is internally implemented (represented) like this: (function name are actually mangled)
struct A
{
int int_in_b1;
};
void Class_A__constructor(struct a*) {} // default constructor
void Class_A__f0(struct a*) {}
void Class_A__f1(struct a*, int x) {a->int_in_b1 = x;}
// new is translated like this: (inline)
void* new() {
void* addr = malloc(sizeof(struc a));
Class_A__constructor(addr);
return addr;
}
It can be verify by doing a command "nm" on the object file (result with mangled named)
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;
}