trustwood项目第二站,Any类型

c++学习,相信我(trustwood),这个谐音还挺好笑的。

每日一问:中国人住什么东西?

好吧,是china(陶瓷)。

我们参考了这篇博文,进行一点warning的修改。

library.h记载的api我们来看看,文件的结构大概如下

#ifndef TRUSTWOOD_LIBRARY_H
#define TRUSTWOOD_LIBRARY_H
#include <iostream>
using namespace std;
class BaseHolder
template<typename T>
class Holder final : public BaseHolder
class Any
class Neuron
#endif //TRUSTWOOD_LIBRARY_H

父类BaseHolder记载存储类型的方法:

class BaseHolder
{
public:
    BaseHolder() = default;
    virtual ~BaseHolder() = default;
    virtual BaseHolder* clone() = 0;
};

子类继承存储实现,如拷贝等,API:

template<typename T>
class Holder final : public BaseHolder
{
public:
    explicit Holder(const T& t)
      : _value(t)
    { }
    ~Holder() override = default;
    BaseHolder* clone() override;
public:
    T _value;
};

Any类API,本章最重要的:

class Any
{
public:
    template<typename ValueType>
    explicit Any(const ValueType& value);
    Any(const Any& any) : _pValue(any._pValue->clone())
    { }
    ~Any();
    template<typename ValueType>
    Any& operator=(const ValueType& value);
    template<typename ValueType>
    ValueType* anyCast();
    template<typename ValueType>
    ValueType& anyRefCast();
private:
    BaseHolder* _pValue;
};

MessageType——一个枚举类,不让用户重复更改消息类型,防止出现意外。

enum MessageType {
    String,integer,Float,Double
};

 上次的神经代码更改如下:

class Neuron {
public:
    Any message;
    Neuron *head = nullptr;
    MessageType type;
    bool getRef;
    string getDescription();
};

 library.cpp我们重写未实现的api

头文件如下,防止没有导入哈,所有的我就已经列举出来了

#include <iostream>
#include <sstream>
#include "library.h"

 Holder的api部分实现

template<typename ValueType>
BaseHolder* Holder<ValueType>::clone()
{
    return new Holder<ValueType>(_value);
}

Any的api部分实现 

Any::~Any() {
    delete _pValue;
}
template<typename ValueType>
Any::Any(const ValueType& value)
{
    _pValue = new Holder<ValueType>(value);
}
template<typename ValueType>
Any &Any::operator=(const ValueType &value) {
    Any tmp(value);
    delete _pValue;
    _pValue = tmp._pValue;
    tmp._pValue = nullptr;
    return *this;
}
template<typename ValueType>
ValueType* Any::anyCast()
{
    auto* p = dynamic_cast<Holder<ValueType>*>(_pValue);
    return p ? &p->_value : NULL;
}
template<typename ValueType>
ValueType& Any::anyRefCast()
{
    return (dynamic_cast<Holder<ValueType>& >(*_pValue))._value;
}

Neuron的枚举对象变量和getRef布尔变量在getDescription中起到了很大的作用,以下是api实现

string Neuron::getDescription() {
    stringstream ss1;
    ss1 << "<Neuron msg=";
    switch (type) {
        case MessageType::String:
            if(getRef) {
                ss1 << message.anyRefCast<string>();
                break;
            }
            ss1 << message.anyCast<string>();
        case MessageType::Float:
            if(getRef) {
                ss1 << message.anyRefCast<float>();
                break;
            }
            ss1 << message.anyCast<float>();
        case MessageType::Double:
            if(getRef) {
                ss1 << message.anyRefCast<double>();
                break;
            }
            ss1 << message.anyCast<double>();
        case MessageType::integer:
            if(getRef) {
                ss1 << message.anyRefCast<int>();
                break;
            }
            ss1 << message.anyCast<int>();
    }
    ss1 << " head=" << this->head << ">";
    return ss1.str();
}

最后可以进行测试,就在library.cpp的末尾,不然一般情况下会有报错

int main() {
    string message = "hello world";
    auto neuron = Neuron(Any(message), new Neuron(Any(2), nullptr, MessageType::integer, false), MessageType::String, true);
    std::cout << neuron.getDescription() << std::endl;
    return 0;
}

CLion运行结果

D:\CLionProjects\trustwood\cmake-build-debug\trustwood.exe
<Neuron msg=hello world head=0x17a229259f0>

Process finished with exit code 0

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值