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