Простой полиморфизм - PullRequest
       1

Простой полиморфизм

1 голос
/ 30 марта 2012

Итак, я явно что-то не так делаю ...

#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() );
}

Я ожидаю, что этот код выведет:

Я ЕСМЬ 2

но вместо этого я получаю:

Я ЕСМЬ 1

"конечная" цель этого проекта - создать LinkedList классов, которые хранят задачи вФорма void WorkClass.Do (void).Каждый встроенный класс был бы отдельной задачей (большинство из них связано с рендерингом интерфейса с моим графическим движком).Я хочу, чтобы EnQueue конструктор, затем, когда DoWork () вызывается, DeQueue WorkClass.Do (), пока я не нажму нулевой указатель.

Я подумал, что возможность сделать эту простую вещь будет хорошим началом для созданиявсе эти другие вещи работают ... но на самом деле я врезался в кирпичную стену.Я предполагаю, что мне придется что-то делать с указателями ...

Ответы [ 3 ]

2 голосов
/ 30 марта 2012

virtual ваш друг.

#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
}

См. Также:

2 голосов
/ 30 марта 2012

Вы берете их по значению, которое их нарезает. Вы должны использовать ссылку или указатель (в этом случае ссылка на константу или ссылку на rvalue, поскольку они являются значениями r)

Обратите внимание на использование ключевого слова virtual. Он необходим только для объявления метода в наследуемых базовом классе членах, которые по умолчанию virtual virtual.

Фиксированная версия на ideone .

1 голос
/ 30 марта 2012

Вы должны прочитать о синтаксисе полиморфизма в C ++.

Во-первых, thingTest должен быть объявлен virtual в базовом классе, прежде чем компилятор выполнит динамический поиск правильной функции времени выполнения длявызывать ссылку или указатель .В вашем текущем коде компилятор исправил функцию во время компиляции до thing1::thingTest, потому что она не помечена как виртуальная.

Во-вторых, вы передаете производный класс по значению типу базового класса.Это может привести к нарезке объектов, т. Е. Члены производного класса будут отрезаны.Вам необходимо передать объект по ссылке или через указатель на DoStuff.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...