2014-01-14 3 views
1

, поэтому у меня возникает проблема вызова функции переопределения производного класса, когда он хранится в массиве его базового класса.Производный объект класса переопределяет функцию базового класса в векторе объектов

Базовый класс называется Obstacle, а производным классом является Cliff. Препятствие имеет виртуальную функцию drawToBackground, а Cliff, которая наследуется от Obstacle, также имеет функцию drawToBackground, обе из которых являются недействительными.

У меня тогда есть вектор препятствий, называемый obstsVec. В этом векторе я храню кучу препятствий и скалы. Теперь скажем, что скала является пятым элементом вектора. Когда я вызываю obstsVec [5] .drawToBackground(); он вызывает функцию drawToBackground из класса Obstacle, а не класса cliff.

Является ли это функцией в C++ или я могу просто что-то объявить неправильно?

Благодаря

+1

Трудно быть уверенным без кода, но я думаю, вам нужно изучить * нарезку объектов *. – juanchopanza

+0

Как вы храните 'Cliff' в' vector '? – Beta

+0

@Beta не уверен. Я прихожу из C# в C++, и я уверен, что это возможно в C#. Думаю, я ошибался, чтобы использовать его в C++. – picklechips

ответ

1

Вы хранящие только базовый класс в своем векторе, так как @juanchopanza уже упоминалось, вы сделали то, что называется объект нарезки. То, что вам нужно сделать, - это полиморфно хранить объекты с помощью указателя.

std::vector<Obstacle*> myObstacles; 
myObstacles.push_back(new Cliff()); 
myObstacles[0]->drawToBackground(); 
// Remember to delete when you're done 

Конечно, если у вас есть доступ к C++ 11, то вы можете забыть о стороне памяти управления вещей:

std::vector<std::unique_ptr<Obstacle>> myObstacles; 
myObstacles.push_back(new Cliff()); 
for (const auto &obstacle : myObstacles) 
{ 
    obstacle->drawToBackground(); 
} 
// No need to delete anything 
+0

Хммм, я не очень хорошо знаком с передовыми материалами, поэтому ни один из этих решений не имеет для меня большого смысла. Что делает myObstacles [0] -> drawToBackground(); делать? Ничто во втором примере не имеет смысла для меня, поэтому я, вероятно, не буду использовать этот метод, если кто-то не сможет объяснить это по строкам для меня. – picklechips

+0

@ RyanMartin Знаете ли вы о указателях на C++? –

+0

Только самые основы. Я знаю, что они указывают на место в памяти, и вы можете получить доступ к этому месту с помощью оператора & или что-то еще. Указатели, вероятно, являются областью, с которой я должен ознакомиться. (Я прихожу из C# в C++, поэтому указатели для меня совершенно новы) – picklechips

2

Ваши классы могли выглядеть примерно так:

#include <iostream> 
#include <vector> 

class Obstacles { 
public: 
    Obstacles() {}; 
    virtual void drawToBackground() { 
    std::cout << "Obstacle "; 
    } 
}; 

class Cliff : public Obstacles { 
public: 
    Cliff() : Obstacles() {}; 
    virtual void drawToBackground() { 
    std::cout << "Cliff "; 
    } 
}; 



int main(int argc, char* argv[]) { 
    std::vector<Obstacles*> vec; 
    vec.push_back(new Obstacles()); 
    vec.push_back(new Cliff()); 
    vec[1]->drawToBackground(); 
    delete vec[1]; 
    delete vec[0]; 
    vec.clear(); 
} 

Вы упомянули вышеприведенные массивы ... никогда не используйте полиморфные массивы, так как это приведет к неопределенному поведению.

Смежные вопросы