Taking address of temporary [-fpermissive] - c++

I know this question is already answered. But I just want to confirm what I understand.
Here is my snippet code. It comes from this.
#include <iostream>
using namespace std;
class Base
{
void a() { cout << "a "; }
void c() { cout << "c "; }
void e() { cout << "e "; }
// 2. Steps requiring peculiar implementations are "placeholders" in base class
virtual void ph1() = 0;
virtual void ph2() = 0;
public:
// 1. Standardize the skeleton of an algorithm in a base class "template method"
virtual ~Base() = default;
void execute()
{
a();
ph1();
c();
ph2();
e();
}
};
class One: public Base
{
// 3. Derived classes implement placeholder methods
/*virtual*/ void ph1() { cout << "b "; }
/*virtual*/ void ph2() { cout << "d "; }
};
class Two: public Base
{
/*virtual*/ void ph1() { cout << "2 "; }
/*virtual*/ void ph2() { cout << "4 "; }
};
int main()
{
Base *array[] =
{
&One(), &Two()
};
for (int i = 0; i < 2; i++)
{
array[i]->execute();
cout << '\n';
}
}
When I compiled, it gives the error as the title:
error: taking address of temporary [-fpermissive]
&One(), &Two()
error: taking address of temporary [-fpermissive]
&One(), &Two()
So, I try to find in the internet. And as they said:
&A() is creating a temporary object which gets destructed on exit of the full expression automagically...
When I changed error line
&One(), &Two()
to
new One(), new Two()
Then, it works.
But, how I make the origin code works like the author wrote? Should I use delete like
delete array[i];

With modern C++ features (11 and above) you can handle such polymorphic arrays with std::vector<std::unique_ptr<Base>>. vector allows automatic destruction and extension, and unique_ptr will destroy the object on its own destruction:
std::vector<std::unique_ptr<Base>> array;
array.emplace_back(new One());
array.emplace_back(new Two());
for(auto &p : array)
p->execute();
// no explicit cleanup is required here
You can choose other smart pointer classes as vector's elements, or even use std::array as fixed size container, but general idea is same for all approaches:
Try not to handle memory management manually, use STL primitives for
such low-level actions.

Related

How do you deep copy a vector of derived class pointers via the copy constructor?

#include <iostream>
#include <string>
#include <vector>
//#include "V2d.h"
using namespace std;
class item {
public:
int value;
string description;
item() {}
virtual ~item() {}
virtual void display() {
cout << "Value: " << value << endl;
}
};
class Cat : public item {
public:
string name = "Cat";
Cat() {
value = 20;
description = "a cat";
}
void display() {
cout << "Name: " << name << endl;
cout << "Value: " << value << endl;
cout << "Description: " << description << "\n" << endl;
}
};
class Dog : public item {
public:
string name = "Dog";
Dog() {
value = 10;
description = "a dog";
}
void display() {
cout << "Name: " << name << endl;
cout << "Value: " << value << endl;
cout << "Description: " << description << "\n" << endl;
}
};
class v2d {
public:
int hitPoints;
enum ItemName {
APPLE, ORANGE
};
vector<item*> inventory;
v2d() {
}
~v2d() {
for (int i = 0; i < inventory.size(); i++) {
delete inventory[i];
}
inventory.clear();
}
v2d(const v2d& orig) : inventory(orig.inventory.size()) {
hitPoints = orig.hitPoints;
for (int i = 0; i < inventory.size(); ++i) {
inventory[i] = new item(*orig.inventory[i]);
}
cout << "Copied!" << endl;
}
void display() {
for (int i = 0; i < inventory.size(); i++) {
inventory[i]->display();
}
}
};
int main() {
v2d vect1;
vect1.inventory.push_back(new Cat());
vect1.inventory.push_back(new Dog());
vect1.inventory.push_back(new Dog());
vect1.inventory.push_back(new Cat());
vect1.inventory.push_back(new Dog());
vect1.display();
cout << "**************************\n" << endl;
v2d vect2(vect1);
vect2.display();
}
And where would I start with trying to overload the += and -= operators in v2d to subtract and add to the inventory vector?
I have gotten to the part of having the base class and the derived classes; I seem to be having trouble not using dynamic casting. Is there a simple way to deep copy a vector of derived class pointers via the copy constructor without using a clone() function?
To do this correctly two more things need to be added to the base class:
class item {
public:
virtual ~item() {}
The base class must have a virtual destructor.
virtual item *clone() const=0;
And an abstract method that's traditionally called clone(). Every one of your subclasses must implement clone(), typically by using a copy constructor:
class Cat : public item {
public:
item *clone() const override { return new Cat{*this}; };
The same thing is done for all other subclasses of item. Then, with this in place you can clone a vector of these objects, correctly:
for (int i = 0; i < inventory.size(); ++i) {
inventory[i] = orig.inventory[i]->clone();
}
I seem to be having trouble not using dynamic casting. Is there a simple way to deep copy a vector of derived class pointers via the copy constructor without using a clone() function?
clone is the traditional solution, but I will propose an alternative.
Consider using type erasure and value types. It will give the simplest use, by far, with more complexity to set it up. Value types generally interoperate more cleanly with a lot of the language and library. They are less intrusive. Standard types can satisfy your interfaces. There is no inheritance required. Value types do not require pointers and indirection everywhere. Those are but a few of the advantages.
With C++20, we can define a concept for item, which is an interface by another name:
template <typename Item>
concept item = std::copyable<Item> && requires(const Item& const_item, Item& item) {
{ item.value() } -> std::same_as<int&>;
{ const_item.value() } -> std::same_as<const int&>;
{ item.description() } -> std::same_as<std::string&>;
{ const_item.description() } -> std::same_as<const std::string&>;
{ item.display() };
{ const_item.display() };
};
Prior to C++20, concepts were generally implicit or documented, but not entities in code. But in C++20, we can define them. Note that this formulation requires std::copyable so any item satisfying this will be copyable, using the standard copy constructor. Also, note that raw data members in an interface complicate things slightly, so I replaced them with accessors while still allowing the public read and write access the code in the question allows.
With the interface defined, one can then define a type-erased version: define a type any_item satisfying item which can itself hold a value of any type satisfying item. You will likely find many online sources about type erasure, and the choices involved. The key is to have storage for the object, and a table of function pointers for the interface (a vtable). One can store the object on the heap or have a small internal buffer for small objects. One can store the vtable inline or store a pointer to the vtable. One can write the vtable explicitly, or rely on a hidden class hierarchy to coerce the compiler into writing one. One can even rely on a library (e.g. dyno) to do this for you.
Note that all this complexity is handled by the interface or library author. The user does not have to inherit anything. The user does not have to define boilerplate clone functions. The user only has to define the functions the concept requires. Then the user can use the type-erased type, and use it like any other value type. The user can put them in a std::vector and watch the copy constructor just work.
Code that looked like:
std::vector<item*> inventory;
~v2d()
{
for (auto* item: inventory) {
delete item;
}
}
v2d(const v2d& orig) :
inventory(orig.inventory.size())
{
for (int i = 0; i < inventory.size(); i++) {
inventory[i] = new item(*orig.inventory[i]);
}
cout << "Copied!" << endl;
}
vect1.inventory.push_back(new Cat());
Becomes:
// just use values
std::vector<any_item> inventory;
// destruction just works
~v2d() = default;
// copy just works
v2d(const v2d& other) :
inventory(other.inventory)
{
std::cout << "Copied!\n";
}
// just use values, again
vect1.inventory.push_back(cat());
See an example

Any techniques or tricks to modifying existing functions in C++?

Within JavaScript, you can pull off something like this:
function bunny() { alert("The bunny jumped."); }
var oldBunny = bunny;
function bunny() {
oldBunny();
alert("The bunny also ran.");
}
bunny(); // The bunny Jumped. The bunny also ran.
As one can see, the old "bunny" function had code appended to it by copying to a variable, then recreating the function with the same name. The copy of the original function runs, and the new code also runs.
I wish to replicate a similar mechanic in C++.
Now before you have a meltdown and start explaining the differences between static and dynamic languages, I get it. I'm not looking for something identical to what's provided, but I do desire something similar.
Furthermore, I'm not trying to do this to modify existing code; I wish to format my own source code to allow such a mechanic for other users to take advantage of.
One of the first ideas I had was to perhaps setup various macros within the code that could later be modified by other files.
Another idea would be to create a Signal and Slots system like in QT. Though I have no clue how to do such a thing myself.
Thank you for reading; I hope you have some suggestions.
Well, if you recognize which feature of JavaScript functions makes this possible, it's not too hard to do the same in C++. In JavaScript functions also have closures, which regular function in C++ don't have. But C++ lambdas are of a closure type. And if one defines bunny to be something which can both hold an object of a closure type, and be reassigned, you're all set.
The C++ standard library offers a nice default choice for this, in the form of std::function. We can just re-write your original JavaScript as follows:
std::function<void()> bunny = [] {
std::cout << "The bunny jumped.\n";
};
auto oldBunny = std::move(bunny);
bunny = [oldBunny] {
oldBunny();
std::cout << "The bunny also ran.\n";
};
bunny();
You can use functors.
#include <iostream>
#include <string>
class Base
{
public:
virtual std::string operator ()()
{
return "Base call";
}
virtual ~Base() {}
};
class Derived : public Base
{
public:
virtual std::string operator()()
{
return "Wrapper: " + Base::operator()();
}
};
int main()
{
Base* pFun = new Base;
std::cout << "Now check Base: " << (*pFun)() << std::endl;
delete pFun;
pFun = new Derived;
std::cout << "Now check Derived: " << (*pFun)() << std::endl;
return 0;
}
Assuming the goal is to allow the calling code to extend the program's functionality beyond what the initial code provided, I might use a user-updatable array of functor-objects, something like this:
#include <iostream>
#include <memory>
class Function
{
public:
virtual void Call() = 0;
};
typedef std::shared_ptr<Function> FunctionSharedPointer;
class OldBunny : public Function
{
public:
virtual void Call()
{
std::cout << "The bunny jumped." << std::endl;
}
};
class NewBunny : public Function
{
public:
NewBunny(FunctionSharedPointer oldFunction) : _oldFunction(oldFunction) {/* empty */}
virtual void Call()
{
_oldFunction->Call();
std::cout << "The bunny also ran." << std::endl;
}
private:
FunctionSharedPointer _oldFunction;
};
enum {
FUNCTION_BUNNY,
// other functions could be declared here later...
NUM_FUNCTIONS
};
// Our table of functions that the user can Call() if he wants to
static FunctionSharedPointer _functionTable[NUM_FUNCTIONS];
// Wrapper function, just to keep users from accessing our table directly,
// in case we ever want to change it to something else
void CallFunction(int whichFunction)
{
_functionTable[whichFunction]->Call();
}
// Another wrapper function
void SetFunction(int whichFunction, FunctionSharedPointer newFunctionDefinition)
{
_functionTable[whichFunction] = newFunctionDefinition;
}
// And another
FunctionSharedPointer GetFunction(int whichFunction)
{
return _functionTable[whichFunction];
}
int main(int argc, char ** argv)
{
// Our default function values get set here
SetFunction(FUNCTION_BUNNY, std::make_shared<OldBunny>());
std::cout << "before:" << std::endl;
CallFunction(FUNCTION_BUNNY);
// Now let's update an entry in our function table to do something different!
FunctionSharedPointer op = GetFunction(FUNCTION_BUNNY);
FunctionSharedPointer np = std::make_shared<NewBunny>(op);
SetFunction(FUNCTION_BUNNY, np);
std::cout << "after:" << std::endl;
CallFunction(FUNCTION_BUNNY);
return 0;
}
void bunny()
{
cout << "The bunny jumped." << endl;
}
void oldBunny()
{
bunny();
}
void newBunny()
{
bunny();
cout << "The bunny also ran." << endl;
}
#define bunny newBunny
int main()
{
bunny();
return 0;
}
If you don't need oldBunny(), just remove it.

c++ decorator pattern, static polymorphism with templates and registering callback methods

I am attempting to use static polymorphism to create a decorator pattern.
As to why I do not use dynamic polymorphism, please see this QA. Basically, I could not dynamic_cast to each decorator so as to access some specific functionality present only in the decorators (and not in the base class A).
With static polymorphism this problem has been overcome, but now I cannot register all the et() methods from the decorators back to the base class A (as callbacks or otherwise), thus when A::et() gets called, only A::et() and Z::et() get executed. I want all of A,X,Y,Z ::et() to be executed (the order for X,Y,Z does not matter).
How can I do that using the following structure?
I can see in wikipedia that CRTP should allow you to access member of a derived class using static_cast, but how do you approach the problem when there are multiple derived template classes?
If this is not possible with static polymorphism but it is possible with dynamic polymorphism could you reply to the other question?
struct I {
virtual void et() = 0;
};
class A : public I {
public:
A() {
cout << "A::ctor " ;
decList.clear();
}
void regDecorator(I * decorator)
{
if (decorator) {
cout << "reg= " << decorator << " ";
decList.push_back(decorator);
}
else
cout << "dec is null!" <<endl;
}
virtual void et()
{
cout << "A::et ";
cout << "declist size= " << decList.size() << endl;
list<I*>::iterator it;
for( it=decList.begin(); it != decList.end(); it++ )
static_cast<I *>(*it)->et();
}
std::list<I*> decList; //FIXME
};
template<typename Base>
class X: public Base {
public:
X(){
cout << "X::ctor ";
Base::regDecorator(this);
}
virtual void et(){
cout << "X::et" <<endl;
}
};
template<typename Base>
class Y: public Base {//public D {
public:
Y(){
cout << "Y::ctor ";
Base::regDecorator(this);
}
void et(){
cout << "Y::et" <<endl;
}
};
template<typename Base>
class Z: public Base {//public D {
public:
Z() {
cout << "Z::ctor ";
Base::regDecorator(this);
}
void et(){
cout << "Z::et" <<endl;
}
};
int main(void) {
Z<Y<X<A> > > mlka;
cout << endl;
mlka.et();
return 0;
}
This structure is to be used as a reference for data acquisition from a set of sensors. class A is the base class and contains common functionality of all the sensors. This includes:
- data container (f.e. `boost::circular_buffer`) to hold an amount of timestamped sample data acquired from the sensor.
- a Timer used to measure some timed quantities related to the sensors.
- other common data and calculation methods (fe. `calculateMean()`, `calculateStdDeviation()`)
In fact the A::timer will call A::et() on completion in order to perform some statistical calculations on the sampled data.
Similarly, X,Y,Z are types of sensor objects each with responsibility to extract different type of information from the sampled data. and X,Y,Z::et() perform a different type of statistical calculation on the data. The aim is perform this calculation as soon as the A::Timer waiting time elapses. This is why I want to have access to all of X,Y,Z::et() from A::et(). Is it possible without affecting the static polymorphism shown in the example?
Thank you
You started using mixins, so use them to the end.
It follows a minimal, working example:
#include<iostream>
struct I {
virtual void et() = 0;
};
template<typename... T>
struct S: I, private T... {
S(): T{}... {}
void et() override {
int arr[] = { (T::et(), 0)..., 0 };
(void)arr;
std::cout << "S" << std::endl;
}
};
struct A {
void et() {
std::cout << "A" << std::endl;
}
};
struct B {
void et() {
std::cout << "B" << std::endl;
}
};
int main() {
I *ptr = new S<A,B>{};
ptr->et();
delete ptr;
}
As in the original code, there is an interface I that offers the virtual methods to be called.
S implements that interface and erases a bunch of types passed as a parameter pack.
Whenever you invoke et on a specialization of S, it invokes the same method on each type used to specialize it.
I guess the example is quite clear and can serve as a good base for the final code.
If I've understood correctly the real problem, this could be a suitable design for your classes.
EDIT
I'm trying to reply to some comments to this answer that ask for more details.
A specialization of S is all the (sub)objects with which it is built.
In the example above, S<A, B> is both an A and a B.
This means that S can extend one or more classes to provide common data and can be used as in the following example to push around those data and the other subobjects:
#include<iostream>
struct I {
virtual void et() = 0;
};
struct Data {
int foo;
double bar;
};
template<typename... T>
struct S: I, Data, private T... {
S(): Data{}, T{}... {}
void et() override {
int arr[] = { (T::et(*this), 0)..., 0 };
(void)arr;
std::cout << "S" << std::endl;
}
};
struct A {
void et(Data &) {
std::cout << "A" << std::endl;
}
};
struct B {
void et(A &) {
std::cout << "B" << std::endl;
}
};
int main() {
I *ptr = new S<A,B>{};
ptr->et();
delete ptr;
}

How to use shared_ptr in a decorator pattern implementation correctly?

I am getting memory leak issues in the following code. I understand there are some flows. But not sure. How to use shared_ptr in these scenarios? And in case I need to add more decorators, say Chocolate-Pista-Icecream, how to pass the pointer correctly such that it will get deleted at the exit?
class AbstractCream
{
public:
virtual void ShowFlavour() = 0;
virtual ~AbstractCream()
{
cout << endl << "AbstractCream-DTOR";
}
};
class IceCream :public AbstractCream
{
public:
void ShowFlavour()
{
cout << "IceCream";
}
~IceCream()
{
cout << endl << "IceCream Dtor";
}
};
class DecoratorCream :public AbstractCream
{
private:
std::shared_ptr<AbstractCream> AbCream;
public:
DecoratorCream(std::shared_ptr<AbstractCream>abs) :AbCream(abs)
{}
void ShowFlavour()
{
AbCream->ShowFlavour();
}
virtual ~DecoratorCream()
{
cout << endl << "DecoratorCream-DTOR";
}
};
class ChocolateCream : public DecoratorCream
{
public:
ChocolateCream(std::shared_ptr<AbstractCream>abs) :DecoratorCream(abs)
{}
void ShowFlavour()
{
cout << "CholocateCream added..";
DecoratorCream::ShowFlavour();
}
~ChocolateCream()
{
cout << endl << "ChocolateCream-DTOR";
}
};
class PistaCream : public DecoratorCream
{
public:
PistaCream(std::shared_ptr<AbstractCream> abs) :DecoratorCream(abs)
{}
void ShowFlavour()
{
cout << "PistaCream added..";
DecoratorCream::ShowFlavour();
}
~PistaCream()
{
cout << endl << "PistaCream-DTOR";
}
};
class StrawberryCream : public DecoratorCream
{
public:
StrawberryCream(std::shared_ptr<AbstractCream> abs) :DecoratorCream(abs)
{}
void ShowFlavour()
{
cout << "StrawberryCream added..";
DecoratorCream::ShowFlavour();
}
~StrawberryCream()
{
cout << endl << "StrawberryCream-DTOR";
}
};
int main()
{
std::shared_ptr <AbstractCream> ice1( new IceCream());
std::shared_ptr <PistaCream> pista1(new PistaCream(ice1));
std::shared_ptr <AbstractCream> ice2(new IceCream());
std::shared_ptr <ChocolateCream>choco1( new ChocolateCream(ice2));
pista1->ShowFlavour();
cout << endl;
choco1->ShowFlavour();
cout << endl;
getchar();
_CrtDumpMemoryLeaks();
return 0;
}
The problem doesn't seem to be the std::shared_ptr<...> use in your classes: that seems to be semantically correct (it is too much code to review in detail, though). Instead, I think your main() is wrong: you try to determine memory leaks at point in time when the objects are still alive. I'm not a Windows program but I'm pretty sure that _CrtDumpMemoryLeak() doesn't know about std::shared_ptr<...> and simply reports newed memory which isn't deleted, yet.
There are a couple of simply ways to change your main() to avoid the problem:
Put the allocation of objects into a block and report memory leaks after the block:
int main() {
{
std::shared_ptr <AbstractCream> ice1( new IceCream());
// ...
}
_CrtDumpMemoryLeaks();
}
Put the code doing the actual work into a separate function and in main() just call this function and report on memory leaks:
int actualMain() {
std::shared_ptr <AbstractCream> ice1( new IceCream());
// ...
}
int main() {
int rc = actualMain();
_CrtDumpMemoryLeaks();
}
Report memory leaks from the destructor of an object which is constructed early, e.g., first thing in main():
struct Reporter { ~Reporter() { _CrtDumpMemoryLeaks(); } };
int main() {
Reporter reporter;
std::shared_ptr <AbstractCream> ice1( new IceCream());
// ...
}
With all three approaches the std::shared_ptr<...>s are destroyed before memory leaks are reported. I'm pretty sure that all of these approaches make the memory leaks go away. My preference would be the use of the third approach.
That said, the way the std::shared_ptr<...> are passed isn't ideal from a performance point of view: increments the reference count each time. When passing it through multiple layers it is unnecessarily bumped up while calling and bumped down when returning from the call. There are multiple ways to fix that problem, too:
The simple approach is to pass the std::shared_ptr<...> as a constant reference:
ChocolateCream(std::shared_ptr<AbstractCream> const& abs)
: DecoratorCream(abs) {
}
It can be argued that the pass by reference inhibits copy elision. However, argument construct can only be elided over one level: when passing the object on to another function it is a named object and the rules for copy elision allow eliding the copy from named objects only for return and throw statements. It may still be reasonable to go that route for the inner-most constructor. Even then, the std::shared_ptr<...> should be moved when passing it on (in that case to the construction of the member variable):
DecoratorCream(std::shared_ptr<AbstractCream> abs)
: AbCream(std::move(abs)) {
}
If you want to pass the argument by value in the other constructors, too, you should, at least, std::move(...) the argument. Doing so should avoid the reference count but it still won't avoid all work as it needs to construct/destroy a std::shared_ptr<...> on each level. However, at least, the synchronized maintenance of the reference count would be avoided.
Since I mentioned a performance problem: stop using std::endl. It doesn't do you much good. In your use it just slows down the program.
class AbstractCream
{
public:
virtual void ShowFlavour() = 0;
virtual ~AbstractCream()
{
cout << endl << "AbstractCream-DTOR";
}
};
class IceCream :public AbstractCream
{
public:
void ShowFlavour()
{
cout << "IceCream";
}
~IceCream()
{
cout << endl << "IceCream Dtor";
}
};
class DecoratorCream :public AbstractCream
{
private:
std::shared_ptr<AbstractCream> AbCream;
public:
DecoratorCream(const std::shared_ptr<AbstractCream> &abs) :AbCream(abs)
{}
void ShowFlavour()
{
AbCream->ShowFlavour();
}
virtual ~DecoratorCream()
{
cout << endl << "DecoratorCream-DTOR";
}
};
class ChocolateCream : public DecoratorCream
{
public:
ChocolateCream(const std::shared_ptr<AbstractCream>& abs) :DecoratorCream(abs)
{}
void ShowFlavour()
{
cout << "CholocateCream added..";
DecoratorCream::ShowFlavour();
}
~ChocolateCream()
{
cout << endl << "ChocolateCream-DTOR";
}
};
class PistaCream : public DecoratorCream
{
public:
PistaCream(const std::shared_ptr<AbstractCream> &abs) :DecoratorCream(abs)
{}
void ShowFlavour()
{
cout << "PistaCream added..";
DecoratorCream::ShowFlavour();
}
~PistaCream()
{
cout << endl << "PistaCream-DTOR";
}
};
class StrawberryCream : public DecoratorCream
{
public:
StrawberryCream(const std::shared_ptr<AbstractCream>& abs) :DecoratorCream(abs)
{}
void ShowFlavour()
{
cout << "StrawberryCream added..";
DecoratorCream::ShowFlavour();
}
~StrawberryCream()
{
cout << endl << "StrawberryCream-DTOR";
}
};
//-------------------dec--------------------------------------------------------------//
struct DummyToLeakCheck
{
public:
~DummyToLeakCheck()
{
_CrtDumpMemoryLeaks();
}
};
int main()
{
DummyToLeakCheck myLeakChecker;
std::shared_ptr <AbstractCream> ice1( new IceCream());
std::shared_ptr <PistaCream> pista1(new PistaCream(ice1));
std::shared_ptr <AbstractCream> ice2(new IceCream());
std::shared_ptr <ChocolateCream>choco1( new ChocolateCream(ice2));
std::shared_ptr <StrawberryCream>straw1(new StrawberryCream(choco1));
pista1->ShowFlavour();
cout << endl;
choco1->ShowFlavour();
cout << endl;
straw1->ShowFlavour();
cout << endl;
getchar();
return 0;
}
Using a Leak-checker as mentioned in the first answer helped correcting the original code.Modified code. Ignoring std::endl as of now, since the purpose of the code is to try out smart pointers in decorator pattern.

Accessing the compiled code of a virtual member function

I need to verify the code of a virtual member function in my other code. So how do I get a pointer that points to the correct code?
class MyInterface {
public:
virtual void VirtualMethod() = 0;
};
class MyImplementation : public MyInterface {
private:
int m_value;
public:
MyImplementation() : m_value(0) { }
virtual void VirtualMethod() {
m_value = 1;
}
};
void main(int argc, char* argv[])
{
MyInterface* pInterface = new MyImplementation();
// In my real code on the following line, we do not have access to the declaration of MyImplementation
unsigned int* pFunctionPointer = (unsigned int*)pInterface->VirtualMethod;
// Now we want to access the compiled code of MyImplementation::VirtualMethod.
printf("0x%08x\n", *pFunctionPointer);
}
In my actual code, I do not have access to MyImplementation declaration at all from the "main" function, if you get my drift.
Here's a little bit of code that I hacked up, which (in g++ 4.6.3) appears to give the expected results.
However, before I get downvotes simply because I'm trying to solve an unsolvable probel, this is absolutely relying on "undefined behaviour". Since the standard doesn't even go into how virtual methods are supposed to be implemented with regards to vptr, vtable, etc, there is no way that you can actually implement this without knowing what the compiler does - and of course, a new version, even in a minor revision, or using different compile options of compiler may change this (e.g. debug mode vs release mode could be different - but that would make it hard to mix debug and release or mix code compiled with old and new compilers)
#include <iostream>
using namespace std;
class A
{
public:
virtual void f();
};
class A2
{
public:
virtual void g();
};
class B: public A, public A2
{
public:
virtual void f();
virtual void g();
};
void print_my_addr(const char *name)
{
cout << "Address of " << name << "=" <<
__builtin_return_address (0) << endl;
}
void A::f()
{
print_my_addr(__FUNCTION__);
}
void A2::g()
{
print_my_addr(__FUNCTION__);
}
void B::f()
{
print_my_addr(__FUNCTION__);
}
void B::g()
{
print_my_addr(__FUNCTION__);
}
// p: pointer to a class object to inspect.
// base_number: which base-class to inspect. 0 = first baseclass
// func_no: function number within the baseclass.
// returns the address as a intptr_t
intptr_t findvirt(A *p, int base_number, int func_no)
{
intptr_t **vptr = reinterpret_cast<intptr_t**>(p);
intptr_t *vtable = vptr[base_number];
return vtable[func_no];
}
int main()
{
A a;
B b;
cout << hex << "Address of A::f()" << findvirt(&a, 0, 0) << endl;
a.f();
cout << hex << "Address of B::f()" << findvirt(&b, 0, 0) << endl;
b.f();
cout << hex << "Address of B::g()" << findvirt(&b, 1, 0) << endl;
}