在c++中创建泛型对象的最佳方法
Best way for creating a generic object in C++?
我主要用c#编程,一提到c++我就不知所措。然而,我需要创建一个c++应用程序,因为它只是一个更大的c++解决方案中的一个组件。
<<p> 情况/strong>- 我有一个结构(父),其中包括一个数据组件(对象)。这可以是任何类型的数据组件,也就是自定义结构。
- 只有父组件的编译器(创建父组件的编译器)和接收端需要知道对象中数据组件的类型,因为数据只与他们相关。
- Parent结构可以传递几个方法、对象,甚至传递给其他进程。 对象的数据选项是有限的,编译器和反编译器都知道数据类型的不同选项。因此,他们能够以原始形式反编译对象
- 然而,类型可以扩展(即,虽然有限,但不一定是固定的)和将来更新的反编译器和编译器
-我不想用"模板"重新创建可能遇到该数据组件的每个方法和对象…此外,考虑到数据类型将来可能会被更改,这表明在长期运行中遇到该对象的每个进程的模板并不是理想的开始。
我正在寻找类似于c# Object的东西-并编写了以下组件
- 这是一个好的解决方案吗?或者我将来会遇到问题吗?
- 在这方面有什么可以改进的吗?这是我没有想到的(特别是没有包括Objectimpl.h?
- 有没有完全不同/更好的解决方案?
在我的头文件
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(); };
我也有一个CreateType函数,用于在开始时创建几个现成的对象,例如目的在.h文件
结尾如下所示 template class CreateType<int>;
请记住int只是一个例子…它实际上是不同的结构体。
我还有另一个头文件,它包含在这个头文件的底部,如下所示:
#include "ImplementationObject_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; }
我希望我可以在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
一般来说,我们避免任何类似对象类型的东西。如果绝对有必要的话,我们可以使用boost::any.
关于你的代码:这实际上是令人印象深刻的好,但这里有一些我要提一下:
没有析构函数。这是一个重大错误。
virtual ~Object() {}
//and
virtual ~ObjectType() {}
同样,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;
}
另外,我会禁止复制和移动赋值位,这有助于防止错误。
class Object {
Object(const Object&) = delete;
Object(Object&&) = delete;
Object& operator=(const Object&) = delete;
Object& operator=(Object&&) = delete;
//stuff
};
我将给派生类型一个默认构造函数和转换构造函数
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
最后,使用智能指针代替原始所属指针。原始指针是可以的,只要它们不拥有它们所指向的对象。
std::unique_ptr<Object> a;
a.reset( new ObjectType<testing>() );
相关文章:
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- 在C++中向零方向近似的最佳方法
- 使用不同的CRT将新的C++代码与旧的(二进制)组件隔离开来的最佳方法是什么
- 检测win32服务创建和删除的最佳方法
- 在C++中样板"冷/never_inline"错误处理技术的最佳方法是什么?
- 在 c++ 中对类中的 c 字符串动态数组进行排序的最佳方法是什么?
- 将线程中的数据存储到全局容器的最佳方法?
- 将一系列整数放入类的最佳方法是什么?
- 在派生类中使用基类的私有成员变量的最佳方法
- 在 C++ 中将非指定类型作为参数传递的最佳方法?
- Qt - QVector 和模型视图 - 从列表视图获取自定义类的最佳方法是什么?
- 使用 Git 处理 C++ Visual Studio 2019 解决方案的外部依赖项源代码管理的最佳方法是什么?
- 比较两个节点坐标的最佳方法是什么?
- 在nodejs中使用本机代码的最佳方法是什么?
- 将 pybind11 绑定标记为已弃用的最佳方法
- C++:将向量传递到构造函数以创建成员变量的最佳方法?
- C++中变量混叠的最佳方法
- 读取大文件(>2GB)(文本文件包含以太网数据)并通过不同参数随机访问数据的最佳方法是什么?