DaC*_*lan 7 c++ generics struct
主要使用C#进行编程后,我发现自己在C++方面处于亏损状态.然而,我需要创建一个C++应用程序,因为它只是一个更大的C++解决方案中的一个组件.
情况
问题 - 我不想使用"模板"重新创建可能遇到此数据组件的每个方法和对象...也看到将来可能更改数据类型建议每个进程遇到长对象的模板开始并不理想.
我正在寻找类似于C#Object的东西 - 并编写了以下组件
题
代码
我的Header文件中有以下内容
struct Object
{
Object();
// Return true if value has succesfully been set
// Return false if there is no compatibility between Value and result.
template <typename T>
bool GetValue(T &result);
template<typename T>
bool SetValue(T value);
virtual LPVOID GetObjectAddress() = 0;
virtual const char* GetType() = 0;
};
template<typename T>
struct ObjectType:public Object
{
ObjectType(T value);
T Value;
LPVOID GetObjectAddress();
const char* GetType();
};
Run Code Online (Sandbox Code Playgroud)我还有一个CreateType函数用于在开始时创建几个现成的对象,例如在.h文件的末尾调用如下目的
template class CreateType<int>;
Run Code Online (Sandbox Code Playgroud)
请记住,int只是例如......它实际上是不同的结构.
我还有另一个头文件,它包含在这个头文件的底部,如下所示:
#include "Implementation\Object_impl.h"
-> looks like this
template<typename T>
ObjectType<T>::ObjectType(T value)
{
Value = value;
};
template <typename T>
// Return true if value has succesfully been set
// Return false if there is no compatibility between Value and result.
bool Object::GetValue(T &result)
{
if (typeid(result).name() == GetType())
{
result = *(T *)GetObjectAddress();
return true;
}
return false;
};
template<typename T>
bool Object::SetValue(T value)
{
if (typeid(T).name() == GetType())
{
*(T*)GetObjectAddress() = value;
return true;
}
return false;
};
template<typename T>
const char* ObjectType<T>::GetType()
{
return typeid(Value).name();
}
template<typename T>
EXPOBJ LPVOID ObjectType<T>::GetObjectAddress(){
return (LPVOID)&Value;
}
Run Code Online (Sandbox Code Playgroud)我希望我可以在cpp文件中包含大部分内容,但是后来我无法按需创建不同的对象......我还不确定其含义是什么......还要扩展类型只需要一个包括普通对象头文件.
我知道内联可能是一个选项,但也认为它不理想?
然而,目前这个编译并完美地作为"通用"选项.还可以通过继承自"Object"继承来扩展吗?
...哦,并使用我只是这样做 - 这似乎工作:
Object * a;
a = new ObjectType<testing>(testing());
testing x = testing();
x.i = 50;
a->SetValue(x);
testing y = testing();
testing &z = y;
a->GetValue(z);
cout << z.i << " for z and y = " << y.i << endl;
Result -> 50 for z and y = 50
Run Code Online (Sandbox Code Playgroud)
至于你的代码:这实际上是非常好的,但这里我提到的一点:
你没有析构函数.这是一个主要的错误.
virtual ~Object() {}
//and
virtual ~ObjectType() {}
Run Code Online (Sandbox Code Playgroud)
此外,GetObjectAddress不是类型安全的.
class Object {
//stuff
template<class T>
T* GetObjectAddress();
private:
virtual LPVOID GetRawPointer() = 0;
};
template<class T>
inline T* Object::GetObjectAddress()
{
if (typeid(T).name() == GetType() || typeid(T).name()==typeid(void).name())
{
return static_cast<T*>(GetRawPointer());
}
return nullptr;
}
Run Code Online (Sandbox Code Playgroud)
此外,我会禁止复制和移动分配位,这有助于防止错误.
class Object {
Object(const Object&) = delete;
Object(Object&&) = delete;
Object& operator=(const Object&) = delete;
Object& operator=(Object&&) = delete;
//stuff
};
Run Code Online (Sandbox Code Playgroud)
我会给派生类型一个默认的构造函数和转换构造函数
template<typename T>
struct ObjectType:public Object
{
ObjectType() {}
//C++11 here:
template<class...Ts>
ObjectType(Ts...Vs)
:Value(std::forward<Ts>(Vs)...) {}
//C++03 here:
template<class first>
ObjectType(const first& f) : Value(f) {}
template<class t0, class t1>
ObjectType(const t0& p0, const t1& p1) : Value(p0, p1) {}
template<class t0, class t1, class t2>
ObjectType(const t0& p0, const t1& p1, const t2& p2) : Value(p0, p1, p2) {}
//etc etc etc
Run Code Online (Sandbox Code Playgroud)
最后,使用智能指针而不是原始拥有指针.原始指针很好,只要他们不拥有他们指向的东西.
std::unique_ptr<Object> a;
a.reset( new ObjectType<testing>() );
Run Code Online (Sandbox Code Playgroud)