Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[C++] Inheritance Diamond Problem
#1
I will just leave it here...

    C++-Code:
#include <iostream>
 
using namespace std;
 
class Root
{
    public: virtual int foo()
    {
        return 0;
    }
};
class Mid1 : Root
{
    public: int foo()
    {
        return 1;
    }
};
class Mid2 : Root
{
    public: int foo()
    {
        return 2;
    }
};
class Top : Mid1, Mid2 //changing order changes output
{
 
};
 
void bar(void* ptr)
{
    Root* root = (Root*)ptr;
    cout << root->foo();
}
 
int main()
{
    Top* t = new Top();
    bar(t);
 
    return 0;
}
Ultimately, my constant dissatisfaction with the way things are becomes the driving force behind everything I do.
[Image: sigline.png]
LF2 IDE - Advanced visual data changer featuring instant data loader
LF2 Sprite Sheet Generator - Template based sprite sheet generator based on Gad's method
[Image: sigline.png]
There is no perfect language, but C++ is the worst.
Reply
Thanks given by:
#2
I suppose you're posting this to discuss the problem rather than look for an answer?

Interesting. I expected it would return 0 since it's being casted to Root, but no matter how I explicitly cast it to Mid2 after it was casted to Root, it would still output 1 for some reason. It's as if the Top object completely 'forgets' the virtual method of Root.
[Image: signature.png]
A-Engine: A new beat em up game engine inspired by LF2. Coming soon

A-Engine Dev Blog - Update #8: Timeout

Reply
Thanks given by:
#3
(01-06-2016, 07:59 PM)Nightmarex1337 Wrote:  changing order changes output
Not really surprising. The base classes have an offset depending on the order they are specified in, and since both of them have a non-zero size (due to the vpointer), their order differ. C-casting to a void pointer discards the type-information, at which point you are in dangerous territory.

(01-06-2016, 07:59 PM)Nightmarex1337 Wrote:  
    C++-Code:
Top* t = new Top();
Why not just construct on the stack?
    C++-Code:
Top t;
Age ratings for movies and games (and similar) have never been a good idea.
One can learn a lot from reinventing wheels.
An unsound argument is not the same as an invalid one.
volatile in C++ does not mean thread-safe.
Do not make APIs unnecessarily asynchronous.
Make C++ operator > again
Trump is an idiot.
Reply
Thanks given by:
#4
(01-06-2016, 09:10 PM)A-Man Wrote:  I suppose you're posting this to discuss the problem rather than look for an answer?

Interesting. I expected it would return 0 since it's being casted to Root, but no matter how I explicitly cast it to Mid2 after it was casted to Root, it would still output 1 for some reason. It's as if the Top object completely 'forgets' the virtual method of Root.

When we declare a virtual function and redefine it in a derived class; it is ensured that the compiler will call the redefined function from the derived class. It will happen even if we call that function with a pointer or reference to the base class of the object.

IBM even has a small page of this, I think. I can find and link it, if you want.

On a related note, the only way to call the base class function would be to do it explicitly using the scope resolution operator.
Probably. I'm not 100% on that one.
If at first you don't succeed, you're probably not going skydiving again.
Reply
Thanks given by:
#5
(01-06-2016, 09:19 PM)Someone else Wrote:  
(01-06-2016, 07:59 PM)Nightmarex1337 Wrote:  changing order changes output
Not really surprising. The base classes have an offset depending on the order they are specified in, and since both of them have a non-zero size (due to the vpointer), their order differ. C-casting to a void pointer discards the type-information, at which point you are in dangerous territory.
Meh... C/C++ is dangerous anyway... This is often used when dealing with low level C API's like multithreading functions, they usually take 2 parameters: a function pointer, and a void pointer which is the argument passed to the function upon thread start (usually).

(01-06-2016, 09:19 PM)Someone else Wrote:  
(01-06-2016, 07:59 PM)Nightmarex1337 Wrote:  
    C++-Code:
Top* t = new Top();
Why not just construct on the stack?
    C++-Code:
Top t;
C# habits... You "new" everything, even structs.
Ultimately, my constant dissatisfaction with the way things are becomes the driving force behind everything I do.
[Image: sigline.png]
LF2 IDE - Advanced visual data changer featuring instant data loader
LF2 Sprite Sheet Generator - Template based sprite sheet generator based on Gad's method
[Image: sigline.png]
There is no perfect language, but C++ is the worst.
Reply
Thanks given by:
#6
(01-12-2016, 09:13 PM)Nightmarex1337 Wrote:  Meh... C/C++ is dangerous anyway...
Opinion, not evidence.

(01-12-2016, 09:13 PM)Nightmarex1337 Wrote:  This is often used when dealing with low level C API's like multithreading functions, they usually take 2 parameters: a function pointer, and a void pointer which is the argument passed to the function upon thread start (usually).

  1. C++11 has multithreading:
        C++-Code:
    std::thread MyThread(SomeFunction,42,"Hello world!");//does SomeFunction(42,"Hello world!") on another thread
    //stuff on this thread
    MyThread.join(
    );//waits for MyThread to finish

  2. Even if you cannot use std::thread for some reason, the amount of times that you will have to pass anything with multiple inheritance to these functions are even rarer.
  3. Even if you have to pass something with multiple inheritance to another thread, the amount of times where this will matter anyway are even more rare.
Age ratings for movies and games (and similar) have never been a good idea.
One can learn a lot from reinventing wheels.
An unsound argument is not the same as an invalid one.
volatile in C++ does not mean thread-safe.
Do not make APIs unnecessarily asynchronous.
Make C++ operator > again
Trump is an idiot.
Reply
Thanks given by:
#7
(01-12-2016, 10:11 PM)Someone else Wrote:  
(01-12-2016, 09:13 PM)Nightmarex1337 Wrote:  Meh... C/C++ is dangerous anyway...
Opinion, not evidence.
I think there are enough evidence to prove that.

(01-12-2016, 10:11 PM)Someone else Wrote:  C++11 has multithreading
I know C++ have multithreading. I said "when dealing with low level C API's" if you know what I mean.
Ultimately, my constant dissatisfaction with the way things are becomes the driving force behind everything I do.
[Image: sigline.png]
LF2 IDE - Advanced visual data changer featuring instant data loader
LF2 Sprite Sheet Generator - Template based sprite sheet generator based on Gad's method
[Image: sigline.png]
There is no perfect language, but C++ is the worst.
Reply
Thanks given by:
#8
(01-12-2016, 10:26 PM)Nightmarex1337 Wrote:  I think there are enough evidence to prove that.
Then it should not be hard to find some.

(01-12-2016, 10:26 PM)Nightmarex1337 Wrote:  I know C++ have multithreading. I said "when dealing with low level C API's" if you know what I mean.
The solution would be to not deal with low-level C APIs, which the vast majority of the time is trivially simple. When you have to deal with low-level C APIs you write a wrapper for it once, and use that from then on. Better yet, you find some code that already does it and use that.
Age ratings for movies and games (and similar) have never been a good idea.
One can learn a lot from reinventing wheels.
An unsound argument is not the same as an invalid one.
volatile in C++ does not mean thread-safe.
Do not make APIs unnecessarily asynchronous.
Make C++ operator > again
Trump is an idiot.
Reply
Thanks given by:
#9
You deserve a cookie for being such a hardcore C++ guy... Now I can clearly see, that you're a masochist...

My eyes hurt cuz I need to sleep so not gonna respond that (maybe later)
Ultimately, my constant dissatisfaction with the way things are becomes the driving force behind everything I do.
[Image: sigline.png]
LF2 IDE - Advanced visual data changer featuring instant data loader
LF2 Sprite Sheet Generator - Template based sprite sheet generator based on Gad's method
[Image: sigline.png]
There is no perfect language, but C++ is the worst.
Reply
Thanks given by:




Users browsing this thread: 1 Guest(s)