引用是调用基类方法?

时间:2013-11-21 04:12:49

标签: c++ c++11

子引用将调用其父级方法而不是自己的方法的原因是什么?我让父母和孩子都实现了虚拟方法。

问题 - >在这个代码示例中,initial.setup调用State的设置。 < - 问题

void StateMachine::initialState(State& initial)
{   
            initial.setup();
            currentStates.add(&initial);
}

void StateMachine::setup(Actor& actor, HashMap<State>& allStates)
        {
            _actor = &actor;
            _allStates = &allStates;
        }

这是我的控制器,它给状态机一个初始状态:

HashMap<State> _states; //This is defined in Controller
void PlayerController::setup(Actor& actor)
{   
        //Factory* actorFactory = new Factory();
        //actorFactory->setup();

        _actor = &actor;
        _stateMachine.setup(actor, _states);


        DrinkState drinkState(actor, _stateMachine);
        MineState mineState(actor, _stateMachine);
        SingState singState(actor, _stateMachine);
        BrawlState brawlState(actor, _stateMachine);
        SleepState sleepState(actor, _stateMachine);
        IdleState idleState(actor, _stateMachine);
        CombatState combatState(actor, _stateMachine);

        _states.add(idleState.to_string(), idleState);
        _states.add(mineState.to_string(), mineState);
        _states.add(drinkState.to_string(), drinkState);
        _states.add(singState.to_string(), singState);
        _states.add(brawlState.to_string(), brawlState);
        _states.add(sleepState.to_string(), sleepState);
        _states.add(combatState.to_string(), combatState);

        //Put actor in idle state
        _stateMachine.initialState(_states.getValue(idleState.to_string())); //_states.getValue returns a reference
} 

国家之间的关系。

class State
    {   
        protected:
            Actor* _actor;
            IStateCallback* _statemachine;
        public:
            State();
            State(Actor& actor);
            State(Actor& actor, IStateCallback& stateMachine);
            virtual void setup();
            virtual void breakdown();
            virtual void tick(float dTime);
            virtual void registerTransitionCallback(IStateCallback& statemachine);
            virtual void switchState(string nextState);
            virtual string to_string();
            virtual bool operator==(State& s); 
            virtual ~State();
    }; 
class MineState : public State
    {   
        private:
            int successChance;
            int maxGold;
        public:
            ~MineState();
            MineState(Actor& actor);
            MineState(Actor& actor, IStateCallback& statemachine);
            virtual void setup();
            void breakdown();
            virtual void tick(float dTime);
            void switchState(string nextState);
            string to_string();
    };

Hashmap的getValue函数:

template<class T>
    T& HashMap<T>::getValue(string key)
    {   
        int bucket = hashString(key);
        HashNode<T>* temporary = hashMap[bucket];

        while (temporary != NULL)
        {   
            if (key.compare(temporary->getKey()) == 0)
            {   
                return temporary->getValue();
            }   

            temporary = &(temporary->getNextNode());
        }   

        T *ret = NULL;
        return *ret;
        //return (T) NULL;
    } 

1 个答案:

答案 0 :(得分:2)

据我所知,问题是HashMap<State>包含State s。当你打电话:

_states.add(idleState.to_string(), idleState);

这是调用State复制构造函数,并在哈希表中存储基类State - 有关派生类的所有信息都已丢失。你是切片的牺牲品。

由于您无法在容器中存储引用,因此您需要执行其他操作。这有点难看,但是如果你将哈希表更改为:

HashMap<State*> _states;

然后插入State 指针,您将获得您期望的多态行为。 (当然,可以使用像std::unique_ptr这样的智能指针代替原始指针。)