用未定义的行为代替没有指针的多态性

问题描述

我最近在 this question 上询问过这个问题。我已经采用了这种通用方法:

#define COFFEE_GEN_GENERIC_VALUE(CLASS_TYPE) using GenericValue##CLASS_TYPE = coffee::utils::GenericValue<CLASS_TYPE,COFFEE_GENERIC_VALUE_CONFIG_MAX_DERIVED_SIZE_OF_##CLASS_TYPE>

template<typename Base,size_t MaxDerivedSize>
class GenericValue
{
private:
    char buffer[MaxDerivedSize];

public:
    GenericValue() = default;

    template<typename Derived,typename... ConstructorArgs>
    static GenericValue<Base,MaxDerivedSize> create(ConstructorArgs... args)
    {
        static_assert(std::is_base_of<Base,Derived>::value,"Derived must derive from Base.");
        static_assert(sizeof(Derived) <= MaxDerivedSize,"The size specified with the macro COFFEE_GenericValueMaxSize is to small.");
        GenericValue<Base,MaxDerivedSize> result{};
        new ((Derived*) result.buffer) Derived{args...};
        return result;
    }

    template<typename Derived>            
    static GenericValue<Base,MaxDerivedSize> from(Derived* toCopy)
    {
        static_assert(std::is_base_of<Base,"Derived must derive from Base.");
        static_assert(sizeof(Derived) <= sizeof(MaxDerivedSize),MaxDerivedSize> result{};
        memcopy(result.buffer,toCopy,sizeof(Derived));
        return result;
    }
    
    GenericValue(const GenericValue<Base,MaxDerivedSize>& other)
    {
        memcopy(buffer,other.buffer,MaxDerivedSize);
    }
    
    GenericValue(GenericValue<Base,MaxDerivedSize>&& other)
    {
        memcopy(buffer,MaxDerivedSize);
    }

    GenericValue<Base,MaxDerivedSize>& operator=(const GenericValue<Base,MaxDerivedSize);
        return *this;
    }
    
    GenericValue<Base,MaxDerivedSize>& operator=(GenericValue<Base,MaxDerivedSize>&& other)
    {
        coffee::utils::copy(buffer,MaxDerivedSize);
        return *this;
    }

    Base& operator*()
    {
        return *(Base*)buffer;
    }

    Base* operator->()
    {
        return (Base*)buffer;
    }
}

我对这种形式 this website 有想法,它与@Matthias Grün 在我的旧问题上的 awnser 类似。 您使用 COFFEE_GEN_GENERIC_VALUE 宏为 GenericValue<Base,MaxDerivedSize> 创建一个 typedef,大小将通过第二个宏传递给它。这样我的库就可以生成将用于特定基类的适当 GenericValue 类型。它背后的基本思想是将派生类型的整个实例及其 vtable 存储在 buffer 中。您可以像复制常规右值一样复制它。

不幸的是,复制只在某些时候有效,我不知道为什么,根据我的知识,这不会成为问题。如果我删除复制运算符和构造函数,并仅使用该类作为 new 的包装器,它会很好地工作(除非对象并未真正复制)。

有没有人知道可能是什么问题?

当我发现一个不需要发布整个项目的边缘案例时,我会发布一个具体示例。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)