在c++中创建泛型对象的最佳方法

Best way for creating a generic object in C++?

本文关键字:最佳 方法 对象 泛型 c++ 创建      更新时间:2023-10-16

我主要用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>() );