码迷,mamicode.com
首页 > 编程语言 > 详细

C++ 属性类

时间:2018-10-10 20:15:09      阅读:168      评论:0      收藏:0      [点我收藏+]

标签:end   mod   代码   c++   pair   equal   好的   rtu   health   

又一次向目标迈进了...

这次是实现一个物体所拥有的属性类。没什么好说的,非常简单。
因为我是C++新手,不知道对这次的实现有没有什么更好的实现方式。因为这个类对以后的进展很重要,而且,要充分考虑易用性,安全性,以及扩展性……
emmmmmmm................

Quality.h

#include "stdinc.h"
#include "Random.h"
#include "Rational.h"

#pragma once

namespace Lunacia 
{
    static RandomNorm g_rn(0.6, 0.15);

    /*The Quality Type. Each type corresponds to a class.*/
    enum class QualityType : uint32_t
    {
        HEALTH = 1,
        COURAGE = 2,
        ACTIVE = 4,
        INTELLIGENCE = 8,
        CREATITY = 16,
        LIFE_INSTINCT = 32
    };

    /*The base quality class.*/
    class Quality 
    {
    protected:
        /*Only class QualitiesManager can instantiate it.*/
        Quality() = delete;
        Quality(QualityType type);

        virtual ~Quality();

    public:
        Quality& operator=(const Quality&) = delete;

    public:
        void SetValue(int32_t val);
        void AddValue(int32_t inc);
        int32_t GetValue() const;

        QualityType GetType() const;

        void SetLimit(int32_t max);

        bool AddPassive(Quality*const & passive);
        bool RemovePassive(QualityType type);

        bool Cut(Quality*& otherQual);

        void Clear();
        static void Clear(Quality*& pQual);

    protected:
        virtual void PassiveImpact(const Quality*const & active) = 0;

        /*Notify all passives when the value is modified.*/
        void NotifyAll();

        void SetType(QualityType type);

    protected:
        QualityType m_type;
        Rational<int32_t> m_value;

        std::unordered_map<QualityType, Quality* const > m_passives;
    };

    typedef Quality*const & PtrQuality;
};

Quality.cpp

#include "Quality.h"

namespace Lunacia
{
    Quality::Quality(QualityType type):
        m_type(type)
    {
        m_value(0, 1000);
        m_value.SetDenomFixed(false);
    }


    Quality::~Quality()
    {
        Clear();
    }

    void Quality::SetValue(int32_t val)
    {
        int32_t& selfVal = m_value._numer;
        selfVal = val;

        if (selfVal > m_value._denom)
        {
            selfVal = m_value._denom;
        }

        if (selfVal < 0)
        {
            selfVal = 0;
        }

        NotifyAll();
    }

    void Quality::AddValue(int32_t inc)
    {
        SetValue(inc += m_value._numer);
    }

    int32_t Quality::GetValue() const
    {
        return m_value._numer;
    }

    QualityType Quality::GetType() const
    {
        return m_type;
    }

    void Quality::SetType(QualityType type)
    {
        m_type = type;
    }

    void Quality::SetLimit(int32_t max)
    {
        if (max <= 0) return;

        const float insRatio = max * 1.0f / m_value._denom;

        m_value._denom = max;
        if (m_value > 1)
        {
            m_value._numer = max;
        }
        else 
        {
            m_value._numer = static_cast<int32_t>(insRatio * m_value._numer);
        }
    }

    bool Quality::AddPassive(Quality*const & passive)
    {
        if (passive == nullptr)
        {
            return false;
        }

        return m_passives.insert(std::pair(passive->m_type, passive)).second;
    }

    bool Quality::RemovePassive(QualityType type)
    {
        return m_passives.erase(type) == 1;
    }

    bool Quality::Cut(Quality *& otherQual)
    {
        if (otherQual == nullptr || (m_type != otherQual->GetType()))
        {
            return false;
        }

        m_value = otherQual->GetValue();
        m_passives = otherQual->m_passives;

        Quality::Clear(otherQual);
        return true;
    }

    void Quality::Clear()
    {
        m_passives.clear();
        m_value = 0;
    }

    void Quality::Clear(Quality *& pQual)
    {
        if (pQual == nullptr)
        {
            return;
        }
        pQual->Clear();
        delete pQual;
        pQual = nullptr;
    }

    void Quality::NotifyAll()
    {
        for (auto& each : m_passives)
        {
            Quality* const& passive = each.second;
            if (passive != nullptr)
            {
                passive->PassiveImpact(this);
            }
        }
    }

};

QualitiesManager.h

#pragma once
#include "Quality.h"

namespace Lunacia
{
    class QualitiesManager
    {
    public:
        QualitiesManager();
        QualitiesManager(uint8_t qualMaxCount);
        ~QualitiesManager();

        friend class Quality;

    public:
        void Clear();

    public:
        Quality* const& AddQuality(Quality* pQual);

        template<class T, typename  std::enable_if <std::is_base_of<Quality, T>::value, T> ::type * = nullptr >
        Quality* const& AddQuality();

        bool RemoveQuality(QualityType type);
        void RemoveAll();

        //void DestoryQuality(Quality*& pQual);

        template<class T, typename  std::enable_if <std::is_base_of<Quality, T>::value, T> ::type * = nullptr >
        Quality* const CreateQuality();

    private:
        std::unordered_map<QualityType, Quality* > m_qualities;
    };

    ////////////////////////////////////////////////////////////////////////////////////////////////////
    //inline void QualitiesManager::DestoryQuality(Quality*& pQual)
    //{
    //  Quality::Clear(pQual);
    //}

    template<class T, typename  std::enable_if <
            std::is_base_of<Quality, T>::value,
        T> ::type *>
    inline Quality * const QualitiesManager::CreateQuality()
    {
        return new T();
    }

    template<class T, typename  std::enable_if <
            std::is_base_of<Quality, T>::value,
        T> ::type *>
    Quality * const& QualitiesManager::AddQuality()
    {
        return AddQuality(CreateQuality<T>());
    }
};

QualitiesManager.cpp

#include "QualitiesManager.h"


namespace Lunacia
{
    QualitiesManager::QualitiesManager()
    {
        m_qualities.reserve(10);
    }

    QualitiesManager::QualitiesManager(uint8_t qualMaxCount)
    {
        m_qualities.reserve(qualMaxCount);
    }

    QualitiesManager::~QualitiesManager()
    {
        Clear();
    }

    void QualitiesManager::Clear()
    {
        for (auto& each : m_qualities) 
        {
            Quality::Clear(each.second);
        }
        m_qualities.clear();
    }

    Quality* const& QualitiesManager::AddQuality(Quality* pQual)
    {
        //Cover add.
        QualityType type = pQual->GetType();
        if (m_qualities.find(type) != m_qualities.end())
        {
            Quality*& qual = m_qualities.at(type);
            qual->Cut(pQual);

            return qual;
        }
        auto resIt = m_qualities.insert(std::pair(type, pQual));

        return resIt.first->second;
    }

    bool QualitiesManager::RemoveQuality(QualityType type)
    {
        auto found = m_qualities.find(type);
        Quality* qualFound = (found == m_qualities.end()) ? nullptr : found->second;

        for (auto& each : m_qualities)
        {
            each.second->RemovePassive(type);
        }

        Quality::Clear(qualFound);

        return m_qualities.erase(type) == 1;
    }

    void QualitiesManager::RemoveAll()
    {
        Clear();
    }
};

*以下文件为测试用文件。
QualHealth.cpp

#include "QualHealth.h"

namespace Lunacia
{
    QualHealth::QualHealth()
        :Quality(QualityType::HEALTH)
    {

    }

    QualHealth::~QualHealth()
    {

    }

    void QualHealth::PassiveImpact(const Quality * const & active)
    {
        if (active == nullptr) return;

        int32_t val = active->GetValue();
        switch (active->GetType())
        {
        case QualityType::LIFE_INSTINCT:
            m_value._numer += static_cast<int32_t>(val * g_rn.GetRandNum<float>()); //test.
            break;

        default:
            break;
        }
        
        
    }

};

QualHealth.h

#pragma once

#include "Quality.h"

namespace Lunacia
{
    class QualHealth final : public Quality
    {
    public:
        QualHealth();
        ~QualHealth();

    private:
        void PassiveImpact(const Quality*const& active);

    };
};

QualLifeInstinct.cpp

#include "QualLifeInstinct.h"

namespace Lunacia
{
    QualLifeInstinct::QualLifeInstinct()
        :Quality(QualityType::LIFE_INSTINCT)
    {
        SetValue(500);
    }

    QualLifeInstinct::~QualLifeInstinct()
    {
    }

    void QualLifeInstinct::PassiveImpact(const Quality * const & active)
    {
        //Nothing here...
        return;
    }

};

QualLifeInstinct.h

#pragma once

#include "Quality.h"
namespace Lunacia
{
    class QualLifeInstinct final : public Quality
    {
    public:
        QualLifeInstinct();
        ~QualLifeInstinct();

    private:
        void PassiveImpact(const Quality*const & active);
    };

};

main.cpp

#include "Tilee.h"
#include "Location.h"
#include "stdinc.h"
#include "Random.h"
#include "Rational.h"
#include "QualitiesManager.h"
#include "QualHealth.h"
#include "QualLifeInstinct.h"

using namespace Lunacia;

struct Item 
{
    uint32_t weight;
    int id;
};

int main(void)
{
    //QualHealth
    QualitiesManager qm;
    PtrQuality ptrQualHealth = qm.AddQuality<QualHealth>();
    PtrQuality ptrQualHealth2 = qm.AddQuality<QualHealth>();

    PtrQuality ptrQualLifeIns = qm.AddQuality<QualLifeInstinct>();

    ptrQualLifeIns->AddPassive(ptrQualHealth);

    ptrQualHealth->AddValue(100);
    ptrQualHealth2->SetValue(432);

    ptrQualLifeIns->AddValue(10);

    qm.RemoveQuality(ptrQualHealth->GetType());

    RandomNorm rn(0.6, 0.15);
    for (size_t i = 0; i < 100; i++)
    {
        std::cout << rn.GetRandNum() << std::endl;
    }

    system("pause");
    return 0;
}

对于漫长的编译时间,我应该仔细考虑一下代码结构了。
下一个,物体类(object class)。

C++ 属性类

标签:end   mod   代码   c++   pair   equal   好的   rtu   health   

原文地址:https://www.cnblogs.com/rkexy/p/9768523.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!