Weird casting behaviour - c++

could somebody explain the output of the code.
#include <iostream>
using namespace std;
class First {
public:
int a;
First() {};
First(int a) {
this->a = a;
}
int getA() {
return a;
}
virtual int getB() {
cout << "getB() from super class..." << endl;
return 0;
}
};
class Second : public First {
public:
int b;
Second(int b) {
this->b = b;
}
int getB() {
cout << "getB() from child class..." << endl;
return b;
}
};
int main() {
First* t = new Second(2);
First* cTest = dynamic_cast<First*>(t);
cout << cTest->getB() << endl;
}
I expected the method of the super class would be called because of the casting to First.
thanks in advance
regards sebastian

The function getB() is virtual in the base class, so you get the derived implementation no matter whether you have a pointer-to-base or pointer-to-derived.
(That's the whole purpose of polymorphism.)

A dynamic cast up the hierarchy doesn't change the fundamental fact that you're still pointing at a B. In particular, it doesn't change the vtable used to find the implementation of getB() that will be used.
Typically, you only need dynamic_cast() to go down an inheritance hierarchy, not up.

There only exists one object, and that is of type Second.
To get the behaviour you are looking for, you are going to have to create a copy and slice it:
First cTest = static_cast<First>(*t);
cout << cTest.getB() << endl;

You aren't changing anything with your cast. You are casting a First* to a First*, which is simply an assignment. Since t is a Second with = new Second(2), you have overridden the virtual table with the child's entries, so it will call the child's methods rather than the parents.
cTest is simply a pointer-to-First which points to the exact same object that t does, because cTest and t contain the same memory address, at which exists a Second object, which is why the Second's method is called.

Related

How to use inheritance to form a generic callback function pointer?

I am trying to write a function that would take in a generic function pointer as an argument.
Suppose you have a class A and its derivatives like below
class A {
};
class A1: public A {
};
class A2: public A {
};
class A3: public A {
};
I have another function
void registerCallback(std::function<void(A*)> func_ptr) {
}
int main() {
std::function<void(A1*)> fptr= [&](A1*) {
cout << "dummy" <<endl;
};
registerCallback(fptr); /// throws error
}
It tells you, cannot convert std::function<void(A*)> to std::function<void(A1*)>
How can I solve this problem?
How can I solve this problem?
You can use A* instead of A1* in the definition of fptr.
std::function<void(A*)> fptr= [&](A*) {
cout << "dummy" <<endl;
};
It is instructive to understand why your code is erroneous, not just from a syntactic point of view but also from a semantic point of view.
From a syntactic point of view, A1* can be used where A* where is expected -- it is an automatic pointer conversion. However, std::function<void(A1*)> cannot be used where std::function<void(A*)> is expected. There is no automatic conversion.
It's more important to understand the semantic problem if that was not
a syntactic error. Let's say for the sake of this discussion that the language/compiler accepted your code. Let's take the code a bit further. Update your code to the following:
class A {
};
class A1: public A {
public:
int int_var;
};
class A2: public A {
public:
double double_var;
};
class A3: public A {
public:
std::string string_var;
};
static std::function<void(A*)> registered_function_ptr;
void registerCallback(std::function<void(A*)> func_ptr) {
registered_function_ptr = fun_ptr;
}
void callRegisteredFunction(A* a_ptr) {
registered_function_ptr(a_ptr);
}
int main() {
std::function<void(A1*)> fptr= [&](A1* a1_ptr) {
// Expecting a pointer to an A1 object.
// Should be able to use members of A1.
cout << "int_var: " << a1_ptr->int_var << endl;
};
registerCallback(fptr);
A2 a2;
a2.double_var = 20;
// Syntactically correct.
callRegisteredFunction(&a2);
A3 a3;
a3.string_var = "Some string";
// Also syntactically correct.
callRegisteredFunction(&a3);
}
When callRegisteredFunction is executed, it calls the registered function. In this case it is fptr. fptr expects a pointer to an A1 object but we are able to call it indirectly with objects that are different -- they don't have int_var. Instead, they have double_var and string_var. That will definitely lead to undefined behavior. The compiler and the language are preventing you falling into that trap.
Just declare fptr as a callable object with parameter of basic type - std::function<void(A*)>. It will still accept all classes (publicly) derived from A:
int main() {
std::function<void(A*)> fptr= [&](A*) {
std::cout << "dummy" << std::endl;
};
A1 *a = new A1{};
fptr(a); // all good
}

Derived Get/Set Methods

Imagine I have this code:
class A {
public:
void GetInt() { cout << number << endl; }
void SetInt(int n) { number = n; }
private:
int number = 0;
};
class B : public A {
public:
void GetInt() { cout << number << endl; }
private:
int number = 0;
};
int main() {
B b;
b.SetInt(5);
b.GetInt(); // Prints 0, needs to be 5
return 0;
}
Is there any way to make SetInt() changing B.number without implementing it in B? Imagine I have 500 derived classes from A, and they set their number in the same { number = n; }. Do I have to implement the same SetInt() method 500 times?
The simple way to get what you ask for is this:
class A {
public:
void GetInt() { cout << number << endl; }
void SetInt(int n) { number = n; }
private:
int number = 0;
};
class B : public A {
// don't hide methods inherited from A
// don't add members that are already present (as private member of A)
};
int main() {
B b;
b.SetInt(5);
b.GetInt(); // Prints 5
return 0;
}
Private members are inherited, they just cannot be accessed directly. Though as A does provide public accessors, B has acess to A::number via the setter from A.
PS A method called Get___ should actually return something, not just print the value on the screen.
No, 0 is the correct result. In your class B you create a whole new member B::number which is independent from A:::number. So when you run A::SetInt, that member function changes A::number and when you run B::GetInt, that function accesses A::number which was never set to 5.
Try not to have members in derived types that have the same name as a member in the base class. All it does is create confusion.
In case you really want each derived class to yield and handle its own value in terms of class hierachy separation - which I'd find at least questionable at all in terms of design and problem solution approach - you cannot avoid a minimum amount of code duplication for each derivation. At least you need the member access itself to be duplicated. There are some template/macro tricks to circumvent code explosions here (generic member instrusion), but since I really don't think, that this is what you want to achieve, I do not go into details for now.
Otherwise, idclev 463035818's answer is the way to go.

Code executes derived class method, but gets default parameter from base class method

Can someone explain why the result of the code below would be "class B::1" ?
Why does the virtual method of derived class uses the default parameter of a base class and not his own? For me this is pretty strange. Thanks in advance!
Code:
#include <iostream>
using namespace std;
class A
{
public:
virtual void func(int a = 1)
{
cout << "class A::" << a;
}
};
class B : public A
{
public:
virtual void func(int a = 2)
{
cout << "class B::" << a;
}
};
int main()
{
A * a = new B;
a->func();
return 0;
}
Because default arguments are resolved according to the static type of this (ie, the type of the variable itself, like A& in A& a;).
Modifying your example slightly:
#include <iostream>
class A
{
public:
virtual void func(int a = 1)
{
std::cout << "class A::" << a << "\n";
}
};
class B : public A
{
public:
virtual void func(int a = 2)
{
std::cout << "class B::" << a << "\n";
}
};
void func(A& a) { a.func(); }
int main()
{
B b;
func(b);
b.func();
return 0;
}
We observe the following output:
class B::1
class B::2
In action at ideone.
It is not recommended that a virtual function change the default value for this reason. Unfortunately I don't know any compiler that warns on this construct.
The technical explication is that there are two ways of dealing with default argument:
create a new function to act as trampoline: void A::func() { func(1); }
add-in the missing argument at the call site a.func() => a.func(/*magic*/1)
If it were the former (and assuming that the A::func was declared virtual as well), then it would work like you expect. However the latter form was elected, either because issues with virtual were not foreseen at the time or because they were deemed inconsequential in face of the benefits (if any...).
Because default value is substituted during compilation and is taken from declaration, while real function to be called (A::func or B::func) is determined at runtime.
Because polymorphism in C++ takes effect at run-time, whereas the substitution of default parameters takes effect at compile-time. At compile time, the compiler does not know (and is not supposed to know) the dynamic type of the object to which the pointer a points. Hence, it takes the default argument for the only type it knows for a, which in your example is A *.
(This incidentally is also the reason default parameters are given in interfaces/headers rather than in implementations/definitions. The compiler never inserts the default parameter in the implementation's machine code, but only in the caller's machine code. Technically, the default parameter is the property of the caller; and the caller doesn't know -- and shouldn't need to know -- an object's dynamic type.)

Changing an object from one derived class to another

I have a couple of classes that share a common base class, with the exception that they differ in the way their methods work. So in the example below, Adder and Multiplier are the same except for the way in which their calculation is performed.
Is there a way to change "a" to a Multiplier on the fly? Do I need to implement methods which convert derived classes to each other? e.g. something like
a = a.asMultiplier()?
As you can see in the code below I tried reinterpret_cast to a Multiplier, with no luck, it still acts like an Adder. (gcc OS X v4.2.1)
#include <iostream>
class Base {
protected:
int a,b;
public:
Base(int a, int b) {
this->a = a;
this->b = b;
}
virtual ~Base() { }
virtual int calculate() = 0;
};
class Adder : public Base {
public:
Adder(int a, int b) : Base(a, b) {
}
int calculate() {
return this->a + this->b;
}
};
class Multiplier : public Base {
public:
Multiplier(int a, int b) : Base(a, b) {
}
int calculate() {
return this->a * this->b;
}
};
int main() {
Base* a = new Adder(3,4);
Base* m = new Multiplier(3,4);
std::cout << "Adder gives " << a->calculate() << std::endl;
std::cout << "Multiplier gives " << m->calculate() << std::endl;
a = reinterpret_cast<Multiplier*>(a);
std::cout << "Now adder gives " << a->calculate() << std::endl;
delete a;
delete m;
return 0;
}
The best thing that comes up to me to solve this, is implementing a copy constructor, taking the base class:
class Multiplier : public Base {
public:
Multiplier(int a, int b) : Base(a, b) {
}
explicit Multiplier(const Base& iBase) : Base(iBase.a, iBase.b) {
}
int calculate() {
return this->a * this->b;
}
};
But since I am not the most advanced c++ developer here, it might not be correct or other people might have a better idea, just trying :)
I would propose to decouple the object's data from its operations. This way you can easily construct one object from another, overtaking the data. So your "conversion" will look like this: Multiplier m = new Multiplier(a);
Doing it the way you are asking for is impossible in C++.
This seems to me that you would need utility classes that operate on data: Change your base class to a Data class whose purpose is only to store the data and pass the data explicitly to the Adder, Multiplier etc. classes.
You can still use inheritance in the utility classes if it makes sense after the above refactoring: in this case base would also operate on a Data object, instead of being the Data itself
It is probably a good idea to change your design. In general I would say that it is a good idea to used inheritance when there is some kind of commonality shared by base and derived classes, not only in terms of data, but in terms of behaviour. Whilst not being very helpful advice directly I would suggest maybe reading some books on object oriented design principles. Trying to cast types in the way you are really makes no sense.

How to hack the virtual table?

I would like to know how to change the address of Test which is in the virtual table with that of HackedVTable.
void HackedVtable()
{
cout << "Hacked V-Table" << endl;
}
class Base
{
public:
virtual Test() { cout <<"base"; }
virtual Test1() { cout << "Test 1"; }
void *prt;
Base(){}
};
class Derived : public Base
{
public:
Test()
{
cout <<"derived";
}
};
int main()
{
Base b1;
b1.Test(); // how to change this so that `HackedVtable` should be called instead of `Test`?
return 0;
}
This works for 32-bit MSVC builds (it's a very simplified version of some production code that's been in use for well over a year). Note that your replacement method must explicitly specify the this parameter (pointer).
// you can get the VTable location either by dereferencing the
// first pointer in the object or by analyzing the compiled binary.
unsigned long VTableLocation = 0U;
// then you have to figure out which slot the function is in. this is easy
// since they're in the same order as they are declared in the class definition.
// just make sure to update the index if 1) the function declarations are
// re-ordered and/or 2) virtual methods are added/removed from any base type.
unsigned VTableOffset = 0U;
typedef void (__thiscall Base::*FunctionType)(const Base*);
FunctionType* vtable = reinterpret_cast<FunctionType*>(VTableLocation);
bool hooked = false;
HANDLE process = ::GetCurrentProcess();
DWORD protection = PAGE_READWRITE;
DWORD oldProtection;
if ( ::VirtualProtectEx( process, &vtable[VTableOffset], sizeof(int), protection, &oldProtection ) )
{
vtable[VTableOffset] = static_cast<FunctionType>(&ReplacementMethod);
if ( ::VirtualProtectEx( process, &vtable[VTableOffset], sizeof(int), oldProtection, &oldProtection ) )
hooked = true;
}
The V-Table is an implementation detail.
The compiler is not required to use one (it just happens to be the easiest way to implement virtual functions). But saying that each compiler can (and does) implement it slightly differently as a result there is no answer to your question.
If you ask how do I hack a vtable for a program built with:
Compiler <X> Version <Y> Build <Z>
Then somebody may know the answer.
void HackedVtable()
{
cout << "Hacked V-Table" << endl;
}
class Base
{
public:
virtual Test() { cout <<"base"; }
virtual Test1() { cout << "Test 1"; }
void *prt;
Base(){}
};
class Derived:public Base
{
public:
Test()
{
cout <<"derived";
}
};
typedef void (*FUNPTR)();
typedef struct
{
FUNPTR funptr;
} VTable;
int main()
{
Base b1;
Base *b1ptr = &b;
VTable vtable;
vtable.funptr = HackedVtable;
VTable *vptr = &vtable;
memcpy ( &b1, &vptr, sizeof(long) );
b1ptr->Test();
//b1.Test(); // how to change this so that HackedVtable() should be called instead of Test()
return 0;
}
Under Mac OS X 10.10.3 + gcc 4.8.3, following code works well.
void HackedVtable()
{
cout << "Hacked V-Table" << endl;
}
class Base
{
public:
virtual void Test() { cout << "base" << endl; }
virtual void Test1() { cout << "Test 1" << endl; }
void *prt;
Base(){}
};
class Derived : public Base
{
public:
void Test()
{
cout << "derived" << endl;
}
};
int main()
{
Base b1;
Base* pb1 = &b1;
*(*(void***)pb1) = (void*) HackedVtable;
pb1->Test();
//It works for all the Base instance
Base b2;
Base* pb2 = &b2;
pb2->Test();
//But Derived's virtual function table is separated from Base's
Derived d1;
Derived* pd1 = &d1;
pd1->Test();
*(*(void***)pd1) = (void*) HackedVtable;
pd1->Test();
return 0;
}
Its output:
$ g++ h.cpp; ./a.out
Hacked V-Table
Hacked V-Table
derived
Hacked V-Table
I test the same code under Ubuntu 12.04 + g++ 4.9.0. However, it does not work and arises segmentation fault.
It seems Linux assigns the virtual function table in a read only area (e.g. rodata) to forbid hacking.
I don't think there is a portable way. Mostly because of compiler optimization and different architecture ABI between every target.
But C++ provides you with that exact same capability, why not use it?
void HackedVtable()
{
cout << "Hacked V-Table" << endl;
}
class Base
{
public:
virtual Test() { cout <<"base"; }
virtual Test1() { cout << "Test 1"; }
void *prt;
Base(){}
};
class Derived : public Base
{
public:
Test()
{
HackedVtable(); // <-- NOTE
}
};
int main()
{
Derived b1; // <-- NOTE
b1.Test();
return 0;
}
Another way to achieve the same thing is by cheking similar code:
GObject:
http://en.wikipedia.org/wiki/Gobject
GLib:
http://en.wikipedia.org/wiki/GLib
Vala:
http://en.wikipedia.org/wiki/Vala_%28programming_language%29
Those guys wanted to work with a object and class oriented programming language, but "C++", didn't fit their requisites. Then , they took "plain C", and simulate objects withn records & pointers, including Virtual Method Tables. Eventually got a similar language called "Vala", their own "C++" alike language (with their own V.M.T.).
Another related links:
http://en.wikipedia.org/wiki/Virtual_method_table
http://www.artima.com/insidejvm/ed2/jvmP.html
Cheers.
well its quite easy to figure out. Find hte VTAble pointer (In visual studio its the first 4/8 bytes). Then step into a normal call of Test (into the assembler) and you'll see it jump to the Vtable and then to your test function. To override test just replace the pointer where you jumped from in the VTable.
This is usually called "virtual table hooking" or something like that.
If you are going to use it much, then I suggest the SourceHook library. It was developed for hacking closed source game engines in game mods. For instance, it was used in The Dark Mod before idTech4 became open source.
I don't think the vTable is in read only area because is it dynamically populated. The only way it can fail is when the compiler is absolutely sure which implementation will be called in compile time and skip the vTable lookup with direct function call(de-virtualization).
EDIT: As #groovyspaceman pointed out, I see that I used wrong wording. The vTable class member pointer is mutable, the vTable itself is compiler generated and it depends on the system and the compiler if it can, or cannot be modified.