如何在C ++ std :: map中访问“第二个”模板化对象

时间:2013-12-31 18:30:38

标签: c++

您好我在编码时做出的决定有困难。我正在开发一个游戏,在我的游戏中我已经处理了Object类中的所有内容,而对象类有两个属性,主要是重要属性和点属性。点属性不知何故需要在字符串和int中,有时需要浮点数。 (我不使用boost:variant我知道它可以更简单,因为我在这个网站上搜索过)但我不喜欢坚持使用boost选项,我真的需要在没有它的情况下这样做。所以每个点属性对象都有int和float,例如攻击损坏,在我的系统中是int类型,而攻击率是float类型。我来解决方案是创建一个名为PointAttribute<的包装器模板类。 T>并且它继承了PABase类,因此我可以在不知道类型的情况下将其推送到地图上。

现在我遇到了一个大问题:如何使用pair正确访问地图的第二个元素:

pair< string , PABase > ?

甚至可能吗? 我用我的代码

template< typename T >
PointAttribute< T > * Object::getPointAttributes( const string & oname )
{
    PointAttribute< T > * attribute = static_cast< PointAttribute<T>* >( &pointAttributes[ oname ] );
    cout << "Getting value of : " << oname << " value : " << attribute->getCurrentPoints() << endl;
    return attribute;
}

我不知道我是否做得对。我知道我做错了,我迫切需要帮助来访问第二个信息。

实际上我的代码有效,但是当我检索到我想要的值时,它会返回一个错误值的浮点数。我检查了我的点属性定义的值,它们似乎在我的系统中正确加载它只是当我检索它时返回的值不是我期望的实际值。

我以这种方式调用了这个函数

    float attackRange = Object::getPointAttributes<float>( "attackrange" )->getCurrentPoints();

编辑:

这是我的PABase和PointAttribute的代码&lt; T&gt;:

#ifndef POINTATTRIBUTE_HPP
#define POINTATTRIBUTE_HPP

#include<iostream>
using std::cout;
using std::endl;
using std::cerr;

#include<string>
using std::string;

#include<memory>
using std::unique_ptr;

#include<SFML/Graphics.hpp>

namespace esc
{
    class PABase{ public: virtual ~PABase(){} };

    template< typename T >
    class PointAttribute : public PABase
    {

    public:

        PointAttribute();
        virtual ~PointAttribute();

        void setAttributePoints( T );
        T getAttributePoints() const;

        void increaseCurrentPointsBy( T );
        void decreaseCurrentPointsBy( T );
        void setCurrentPointsTo( T );
        T getCurrentPoints() const;

        void increaseMaxPointsBy( T );
        void decreaseMaxPointsBy( T );
        void setMaxPointsTo( T );
        T getMaxPoints() const;

        void increaseBasePointsBy( T );
        void decreaseBasePointsBy( T );
        void setBasePointsTo( T );
        T getBasePoints() const;

        void resetPointAttribute();

    private:

        void init();

        string attributeName;

        T attributePoints;
        T currentPoints;
        T maxPoints;
        T basePoints;
    };


    template< typename T >
    PointAttribute< T >::PointAttribute()
        :
        attributePoints( T() ),
        currentPoints( T() ),
        maxPoints( T() ),
        basePoints( T() )
    {

    }

    template< typename T >
    PointAttribute< T >::~PointAttribute()
    {

    }

    template< typename T >
    inline void PointAttribute< T >::setAttributePoints( T p )
    {
        attributePoints = p;
        currentPoints   = p;
        maxPoints       = p;
        basePoints      = T();

        cout << "\n\nAttribute set! " << endl;
        cout << "Attribute points : " << attributePoints << endl;
        cout << "Max points       : " << maxPoints << endl;
        cout << "Base points      : " << basePoints << endl;
    }

    template< typename T >
    inline T PointAttribute< T >::getAttributePoints() const
    {
        return attributePoints;
    }

    template< typename T >
    inline void PointAttribute< T >::increaseCurrentPointsBy( T amount )
    {
        currentPoints += amount;
        currentPoints = ( currentPoints > maxPoints )? maxPoints : currentPoints;
    }

    template< typename T >
    inline void PointAttribute< T >::decreaseCurrentPointsBy( T amount )
    {
        currentPoints -= amount;
        currentPoints  = ( currentPoints < T() )? T() : currentPoints;
    }

    template< typename T >
    inline void PointAttribute< T >::setCurrentPointsTo( T amount )
    {
        if( amount >= basePoints && amount <= maxPoints )
            currentPoints = amount;
    }

    template< typename T >
    inline T PointAttribute< T >::getCurrentPoints() const
    {
        return currentPoints;
    }

    template< typename T >
    inline void PointAttribute< T >::increaseMaxPointsBy( T amount )
    {
        int checkVal = ( amount < T() )? T() : amount;
        maxPoints += checkVal;
    }

    template< typename T >
    inline void PointAttribute< T >::decreaseMaxPointsBy( T amount )
    {
        T checkVal = ( amount < T() )? T() : amount;
        maxPoints -= checkVal;
    }

    template< typename T >
    inline void PointAttribute< T >::setMaxPointsTo( T amount )
    {
        T checkVal = ( amount < T() )? T() : amount;
        maxPoints = checkVal;
    }

    template< typename T >
    inline T PointAttribute< T >::getMaxPoints() const
    {
        return maxPoints;
    }

    template< typename T >
    inline void PointAttribute< T >::increaseBasePointsBy( T amount )
    {
        if( amount > T() && amount <= maxPoints )
            basePoints += amount;
    }

    template< typename T >
    inline void PointAttribute< T >::decreaseBasePointsBy( T amount )
    {
        if( amount > T() && amount <= maxPoints )
            basePoints -= amount;
    }

    template< typename T >
    inline void PointAttribute< T >::setBasePointsTo( T amount )
    {
        if( amount > T() && amount <= maxPoints )
            basePoints = amount;
    }

    template< typename T >
    inline T PointAttribute< T >::getBasePoints() const
    {
        return basePoints;
    }

    template< typename T >
    inline void PointAttribute< T >::resetPointAttribute()
    {
        maxPoints  = attributePoints;
        basePoints = T();
    }
}

#endif // POINTATTRIBUTE_HPP

以下是在游戏开始前填充点属性的方法。该定义是使用以下给定语法从简单文本文件加载的:

[pointattribute]
attackdamage 7
attackrange 150

这里是我自制阅读器的一部分,只要它是一个有效的文件符号就可以读取特定的标识符,在这种情况下[pointattribute] 原因是我可以在没有做很多代码的情况下在未来添加更多的点属性,我可以在平衡游戏时随意更改它们。 (我正在为RTS编写一个框架。)

以下是其他内容的摘录 - 如果是读者的一部分

        else if( identifier.compare("[pointattribute]") == 0 )
        {
            string aname;
            string s_eval;

            s >> aname >> s_eval;

            cout << "\n\nLoading point attribute of : " << oname << endl;
            cout << "Attribute name : " << aname << " value : ";

            if( is< float >( s_eval ) )
            {
                istringstream s( s_eval );
                float fval = 0.0f;
                s >> fval;

                PointAttribute< float > wrap;
                wrap.setAttributePoints( fval );

                attrib->pointAttributes[ aname ] = wrap;

                cout << fval << endl;
            }
            else if( is< int >( s_eval ) )
            {
                istringstream s( s_eval );
                int ival = 0;
                s >> ival;

                PointAttribute< int > wrap;
                wrap.setAttributePoints( ival );

                attrib->pointAttributes[ aname ] = wrap;

                cout << ival << endl;
            }
        }

Object类范围内返回的值大约是1.0e。它只返回那种实际数字,实际上并不是我所期望的价值。出了点问题,我严重忽视了一些问题。

此外,我有一个C ++的年轻经验,所以对我的术语感到抱歉,我希望自己清楚。谢谢你的帮助。

0 个答案:

没有答案