1

So, clearly I'm doing something wrong...

#include <iostream>
using namespace std;

class thing1
{
public:
    void thingTest()
    {
        cout << "I AM THING 1\n";
    }
};

class thing2: public thing1
{
public:
    void thingTest()
    {
        cout << "I AM THING 2\n";
    }
};

void DoStuff( thing1 temp )
{
    temp.thingTest();
}


void main()
{
    DoStuff( thing2() );
}

I expect this code to output:

I AM THING 2

but instead I get:

I AM THING 1

the "final" goal of this project is to create a LinkedList of classes that store tasks in the form of void WorkClass.Do( void ). Each inharted class would be a different task (most of them have to do with rendering interface with my graphics engine). I want to EnQueue the constructor, then when DoWork() is called, DeQueue WorkClass.Do() until I hit a null pointer.

I figured being able to do this simple thing would be a good start to making all that other stuff work... but as it is, I've hit a brick wall. I assume I'll have to do something with pointers...

GreenFox
  • 445
  • 1
  • 3
  • 12

3 Answers3

2

You are taking them by value, which is slicing them. You must use reference or pointer (reference to const, or rvalue reference, in this case as they are rvalues)

Note the use of the virtual keyword. It is only needed on the method declaration in the base class- inherited members which are virtual are virtual by default.

A fixed version on ideone.

Puppy
  • 144,682
  • 38
  • 256
  • 465
2

virtual is your friend.

#include <iostream>
using namespace std;

class thing1
{
public:
    // Make this virtual, so that when called by pointer or 
    // by reference, the most derived version is called.
    virtual void thingTest()
    {
        cout << "I AM THING 1\n";
    }
};

class thing2: public thing1
{
public:
    // This is virtual by default, but it's best to be explicit,
    // especially when the next guy derives from thing2.
    virtual void thingTest()
    {
        cout << "I AM THING 2\n";
    }
};

// Pass by value to prevent object slicing
void DoStuff(thing1& temp )
{
    temp.thingTest();
}

// main always returns int
int main()
{
    thing2 x; // Create a thing2
    DoStuff(x); // Pass the rvalue
}

See also:

Community
  • 1
  • 1
johnsyweb
  • 136,902
  • 23
  • 188
  • 247
1

You should read up about the syntax for polymorphism in C++.

First, thingTest has to be declared virtual in the base class before the compiler will perform dynamic lookup for the correct runtime function to invoke on a reference or a pointer. In your current code the compiler has fixed the function at compile time to that of thing1::thingTest because it is not marked as virtual.

Second, you are passing a derived class by value to a base class type. This can result in object slicing, i.e., members of the derived class being cut off. You need to pass the object by reference or through a pointer to DoStuff.

devil
  • 1,829
  • 16
  • 23