I'm assuming this is completely illegal but I was wondering if anyone else has ever used it. It actually seems kind of useful or at least I can think of uses for it. In fact I remember a few years back wanting this feature but at that time I didn't realize you could actually do it. So what's going on below is we are changing the v-table using placement new. Here's the code.....
// ChangeClass.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include "pch.h"
#include <assert.h>
#include <iostream>
/**
****************************************************************************************************
**
****************************************************************************************************
**/
class CGod
{
public:
CGod()
{
}
CGod(int iA, int iB, int iC, int iD) :
m_iA(iA), m_iB(iB), m_iC(iC), m_iD(iD)
{}
void DataIntact()
{
std::cout << "Data Intact! (" << m_iA << "," << m_iB << "," << m_iC << "," << m_iD << ")\n";
}
virtual void WhoAmI()
{
std::cout << "God: \"I am a random god!\"\n";
DataIntact();
}
void *operator new (size_t size, void* ptr)
{
return (void *) ptr;
}
// Keep the compiler from complaining
void operator delete(void* addr, void* ptr)
{
assert(0);
}
virtual ~CGod() {}
public:
int m_iA;
int m_iB;
int m_iC;
int m_iD;
};
/**
****************************************************************************************************
**
****************************************************************************************************
**/
class CBrahma : public CGod
{
public:
CBrahma() {}
void WhoAmI() override
{
std::cout << "Brahma: \"Now I am Brahma!\"\n";
DataIntact();
}
static void Change( CGod *pGod)
{
new(pGod) CBrahma();
}
};
/**
****************************************************************************************************
**
****************************************************************************************************
**/
class CRama : public CGod
{
public:
CRama() {}
void WhoAmI() override
{
std::cout << "CRama: \"Now I am Rama!\"\n";
DataIntact();
}
static void Change( CGod *pGod)
{
new(pGod) CRama();
}
};
/**
****************************************************************************************************
**
****************************************************************************************************
**/
class CVishnu : public CGod
{
public:
CVishnu() {}
void WhoAmI() override
{
std::cout << "Vishnu: \"Now I am become Death, the destroyer of worlds!\"\n";
DataIntact();
}
static void Change( CGod *pGod)
{
new(pGod) CVishnu();
}
};
/**
****************************************************************************************************
**
****************************************************************************************************
**/
int main()
{
CGod *pGod = ::new CGod(1,2,3,4);
pGod->WhoAmI();
CBrahma::Change(pGod);
pGod->WhoAmI();
CRama::Change(pGod);
pGod->WhoAmI();
CVishnu::Change(pGod);
pGod->WhoAmI();
::delete pGod;
}
And here's the output ......
God: "I am a random god!"
Data Intact! (1,2,3,4)
Brahma: "Now I am Brahma!"
Data Intact! (1,2,3,4)
CRama: "Now I am Rama!"
Data Intact! (1,2,3,4)
Vishnu: "Now I am become Death, the destroyer of worlds!"
Data Intact! (1,2,3,4)