Наследование классов C ++, вызов функций класса с помощью указателей - PullRequest
0 голосов
/ 20 февраля 2012

У меня есть базовый класс (виртуальный) с некоторыми детьми и массив с указателями на базовые классы.Когда я создаю новый объект и затем добавляю его адрес в массив, это нормально.Но когда вместо добавления адреса я использую new class (), вызывается функция PARENT, а не CHILD.Пример кода:

class base
{
public:
    virtual int foo() {return 1;};
};

class child : public base
{
  int foo() {return 2;};
};

//somewhere in code...

vector<base*> arr;

//1. Its ok:
child one;
arr.push_back(&one);
cout<<arr[0].foo(); //Its 2

//2. Its not ok...
arr.push_back(new child())

cout<<arr[1].foo(); //Its 1...

Спасибо за помощь ...

РЕДАКТИРОВАТЬ:

Извините, ошибка компилятора - Скачал MinGW и работает нормально ... Извинитедля проблемы ...

Ответы [ 4 ]

2 голосов
/ 20 февраля 2012

Ваш предоставленный пример не должен компилироваться вообще, поскольку вы объявляете vector<base*> и обращаетесь к его элементам с помощью оператора ..Если это скомпилировано, ваш компилятор сломан, так что лучше удалите его и установите достойный.

Кроме этого, сделайте

arr[0]->foo();

и

arr[1]->foo();

Это должно работать нормально.

2 голосов
/ 20 февраля 2012

foo не публично у ребенка

class child : public base
{   
public:
  int foo() {return 2;};
};  

также, пока я здесь, должно быть

arr[0]->foo();

так

child one;
arr.push_back(&one);
arr.push_back(new child());
for(const base* b : arr)//C++11
    std::cout << b->foo() << '\n';

результат

2
2
0 голосов
/ 20 февраля 2012

Я попробовал ваш код с помощью компилятора Apple LLVM и протестировал его. Ваш пробег может варьироваться в зависимости от используемого вами компилятора.

  • 111111 прав в том, что метод должен быть публичным в дочернем классе. LLVM не заботился и дал 2 в результате в обоих случаях.
  • Отсутствует точка с запятой после arr.push_back (new child ());
  • Вы должны ссылаться на arr [0] -> foo () (arr [0] имеет тип base *, вектор указателей)
  • Отсылать ссылку на переменную стека, как правило, плохая идея (просто отмечая, хотя, вероятно, это было сделано, чтобы показать проблему)

По мере ввода новых ответов добавляются!

Вот некоторый рабочий код:

#include <iostream>
#include <vector>

using namespace std;

class base
{
public:
    virtual int foo() {return 1;};
};

class child : public base
{
    int foo() {return 2;};
};

int main (int argc, const char * argv[])
{
    vector<base*> arr;

    //1. Its ok:
    child one;
    arr.push_back(&one);
    cout<<arr[0]->foo() << endl; //Its 2

    //2. Its not ok...
    arr.push_back(new child());

    cout<<arr[1]->foo() << endl; //Its 2...
    return 0;
}
0 голосов
/ 20 февраля 2012

Функция foo должна быть общедоступной.Более того, поскольку у вас есть вектор «указатель на базу» , вы должны разыменовать (*arr[i]) его элементы, чтобы вызвать функцию foo, иначе код не будет построен.

#include <iostream>
#include <stdio.h>
#include <vector>

using namespace std;

class base
{
public:
    virtual int foo() {return 1;};
};

class child : public base
{
public:   // correction # 0
  int foo() {return 2;};
};

int main( int argc, const char* argv[] )
{
    vector<base*> arr;

    child one;
    arr.push_back(&one);
    cout << (*arr[0]).foo() << endl;   // correction # 1

    arr.push_back(new child());
    cout << (*arr[1]).foo() << endl;   // correction # 2
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...