What I\'m actually trying to do is cast a constructed moneypunct
to the punct_facet
in this question without writing a copy constructor as in this answ
So this is implementation specific as Wikipedia notes:
The C++ standards do not mandate exactly how dynamic dispatch must be implemented, but compilers generally use minor variations on the same basic model.
Typically, the compiler creates a separate vtable for each class. When an object is created, a pointer to this vtable, called the virtual table pointer, vpointer or VPTR, is added as a hidden member of this object. The compiler also generates "hidden" code in the constructor of each class to initialize the vpointers of its objects to the address of the corresponding vtable.
Even worse Danny Kalev states:
Compilers can be divided into two categories with respect to their vptr's position. UNIX compilers typically place the vptr after the last user-declared data member, whereas Windows compilers place it as the first data member of the object, before any user-declared data members.
I give all the preceding information to indicate the conditions in which my hack will work:
With understanding of the hack that you are getting into I will now proceed to extend the classes in the question to better demonstrate how we can "Cast to a Child":
class Parent{
public:
Parent operator=(const Parent&) = delete;
Parent(const Parent&) = delete;
Parent() = default;
Parent(int complex) : test(complex) {}
virtual void func(){ cout << test; }
private:
int test = 0;
};
class Child : public Parent{
public:
Child operator=(const Child&) = delete;
Child(const Child&) = delete;
Child() = default;
Child(const Parent* parent){
const auto vTablePtrSize = sizeof(void*);
memcpy(reinterpret_cast(this) + vTablePtrSize,
reinterpret_cast(parent) + vTablePtrSize,
sizeof(Parent) - vTablePtrSize);
}
virtual void func(){ cout << "Child, parent says: "; Parent::func(); }
};
We are simply using memcpy
to copying the state of the parent object, while allowing all Child
information to persist.
You can see that this code:
Parent foo(13);
Child bar(&foo);
bar.func();
Will print:
Child, parent says: 13
Live example and though it's not asked for in the question here's how it could be accomplished for multiple inheritance: http://ideone.com/1QOrMz
This is a useful solution for moneypunct
as it's initialization will be implementation specific anyway, since C++ does not specify any locale names other than:
""
"C"
"POSIX"
I would like to close this answer by pointing out that this entire post has been about how to overcome limitations intentionally put in place by the designers of moneypunct
. So, yes you can do this but as you do the obvious question should be asked: "Why were the copy constructor and assignment operator of moneypunct
deleted in the first place? What aspect of that design am I intentionally subverting?"