C++ 属性类

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

这次是实现一个物体所拥有的属性类。没什么好说的,非常简单。

因为我是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)。

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

时间: 2024-10-28 19:17:24

C++ 属性类的相关文章

波哥学JAVA,定义类 创建对象 实例化对象 属性 类调用属性或者方法

定义类 声明对象  创建对象 实例化对象 属性 对象调用属性或者方法 举例,下面定义类了一个类并声明属性,写了一个方法: 创建对象 实例化对象 属性 类调用属性或者方法

Java属性类:Properties的常用方法

Properties类本身是Hashtable类的子类,也是按照key-value的形式存放数据的. 设置和取得属性: public class PropertiesDemo01{ public static void main(String args[]){ Properties pro = new Properties() ; // 创建Properties对象 pro.setProperty("BJ","BeiJing") ; // 设置属性 pro.setP

从零开始学Java之IO字符流懒人模式(自动生成属性类,方法类,界面类)

平时做一个项目都要建很多的属性类,方法类和View类,学了IO流之后想了一种办法,就是自己写一串代码,然后在文本文档里写class <类名>加上所有的属性,然后运行一下代码就自动生成了一个  <类名>.java   文件.用myeclipse打开就可以了.同样的道理,你写一个只有   class <类名> 的txt文本文档  点一下另一段代码就自动生成了一个方法类,里面带有增删改查四个简单方法的方法类,还有一个View类. 首先说一下,生成属性类的这段代码: packa

Swift-存储属性,计算属性,类属性

//类的属性定义 class Student: NSObject { // 定义属性 // 定义存储属性 var age : Int = 0 var name :String? var mathScore : Double = 0.0 var chineseScore :Double = 0.0 // 定义一个方法,可以是返回平均成绩 (注意: swift不建议这样使用,应该定义一个计算属性) func getAverageScore() -> Double { // 在swift如果是使用当前

springboot属性类自动加载配置文件中的值

springboot属性类自动加载配置文件中的值,如Person类加载在yml中配置的name,age等属性值,可以通过如下步骤获取: 类上添加@ConfigurationProperties注解,prefix为yml中配置的属性名称,要想属性类生效得加上@Component注解 如果想要在yml中有对应类的提示,还需要添加如下依赖: yml书写如下: 如果是properties文件,则书写如下: 在yml中如果值中有特殊字符,需要转义可以用单引号包裹,默认是双引号 如果仅仅为类中的某个属性值赋

属性类:Properties

属性是程序中经常出现的形式. 在类集中提供了一种专门的Properties类. public class Propertiesextends Hashtable<Object,Object> Properties是HashTable子类,那么肯定也是Map子类.可以使用Map的全部操作. 但是一般情况下是单独使用的. 设置和取得属性 设置属性. Object setProperty(String key, String value) 调用 Hashtable 的方法 put. 得到属性: 找到

字段 | 方法 | 属性 | 类的成员 | Python

# ----------------------------------------- 字段 class Class: # 静态字段,属于类 # 已经创建,并且存放在类里,而不是每创建一个对象创建一次; country = '中国' def __init__(self, name): # 普通字段-->> 保存在创建的对象里 self.name = name # 普通方法-->> 保存在类里 def show(self): print(self.name) # 实例化对象 obj

java beanUtilsX操作属性类

// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package cn.com.tisco.upad.common.util.convert; import cn.com.tisco.upad.common.util.ArrayUtilsX; import cn.com.tisco.upad.common.util.validation.

Python高级语法-对象实例对象属性-类与实例,class方法静态方法等(4.6.1)

目录 1.说明 2.代码 关于作者 @ 1.说明 python中属性:类属性,实例属性 方法:类方法,实例方法,静态方法 想修改类属性,只能是类方法,因为只有类方法把cls(类)传入数据里面 静态方法也就是个普通的方法,为了方便而已 实例方法,不能通过类来直接调用,要调用也可以self = 对象名 具体下面 2.代码 class Provice(object): #类属性 country = "china" def __init__(self,name): #实例属性 self.nam