c++ - 创建动态大小的对象

标签 c++

删除了 C 标签,因为它造成了一些困惑(它不应该从那里开始;对于在那里给您带来的任何不便,我们深表歉意。尽管 C 的回答仍然受欢迎 :)

在我所做的一些事情中,我发现需要创建具有动态大小和静态大小的对象,其中静态部分是您的基本对象成员,动态部分是数组/缓冲区直接附加到类上,保持内存连续,从而减少所需分配的数量(这些是不可重新分配的对象),并减少碎片(尽管不利的一面是,可能更难找到足够大的 block , 然而这比堆碎片更罕见 - 如果它甚至应该发生的话。这对于内存非常宝贵的嵌入式设备也很有帮助(但是我目前没有为嵌入式设备做任何事情)和事情像 std::string 需要避免,或者不能像在普通 union 的情况下那样使用。

通常我会采用的方法是(ab)使用 malloc(std::string 不是故意使用的,并且出于各种原因):

struct TextCache
{
    uint_32 fFlags;
    uint_16 nXpos;
    uint_16 nYpos;
     TextCache* pNext;
    char pBuffer[0];
};

TextCache* pCache = (TextCache*)malloc(sizeof(TextCache) + (sizeof(char) * nLength));

然而,这对我来说不太合适,因为首先我想使用 new 来做这个,因此在 C++ 环境中,其次,它看起来很糟糕 :P

所以下一步是模板化的 C++ 变体:

template <const size_t nSize> struct TextCache
{
    uint_32 fFlags;
    uint_16 nXpos;
    uint_16 nYpos;
     TextCache<nSize>* pNext;
    char pBuffer[nSize];
};

然而,这有一个问题,即存储指向可变大小对象的指针变得“不可能”,因此接下来的工作是:

class DynamicObject {};
template <const size_t nSize> struct TextCache : DynamicObject {...};

然而,这仍然需要转换,并且当有多个动态大小的对象派生自它时,到处都有指向 DynamicObject 的指针会变得不明确(它看起来也很糟糕,并且可能会遇到一个错误,该错误会强制空类仍然具有大小,尽管这可能是一个古老的、已灭绝的错误...)。

然后是这样的:

class DynamicObject
{
    void* operator new(size_t nSize, size_t nLength)
    {
        return malloc(nSize + nLength);
    }
};

struct TextCache : DynamicObject {...};

这看起来好多了,但是会干扰已经有 new 重载的对象(它甚至可能影响 placement new...)。

最后我想出了放置新的滥用:

inline TextCache* CreateTextCache(size_t nLength)
{
    char* pNew = new char[sizeof(TextCache) + nLength];
    return new(pNew) TextCache;
}

然而,出于多种原因,这可能是迄今为止最糟糕的想法。

那么有没有更好的方法来做到这一点?或者上述版本之一会更好,或者至少可以改进?这样做甚至被认为是安全和/或糟糕的编程实践吗?


正如我上面所说的,我试图避免双重分配,因为这不需要两次分配,这使得将这些东西写入(序列化)到文件中变得容易得多。 我的双重分配要求的唯一异常(exception)是它的开销基本上为零。我遇到的唯一原因是我从固定缓冲区( using this system ,我想出了)顺序分配内存,但它也是防止过度复制的特殊异常(exception)。

最佳答案

我会寻求与 DynamicObject 概念的妥协。所有不依赖于大小的东西都进入基类。

struct TextBase 
{ 
    uint_32 fFlags; 
    uint_16 nXpos; 
    uint_16 nYpos; 
     TextBase* pNext; 
}; 

template <const size_t nSize> struct TextCache : public TextBase
{ 
    char pBuffer[nSize]; 
}; 

这应该会减少所需的转换。

关于c++ - 创建动态大小的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3659946/

相关文章:

c++ - 为什么没有一元运算符来获得乘法逆元? 0-x = -x ... 1/x =?

c++ - 用常量初始化数组不起作用

c++ - 使用 Xcode 13 在 iOS 15 上编译 Cronet 时,shrink_to_fit() 的 "Undefined symbols"

c++ - enable_if 模板函数的关键顺序

c++11 在头文件中无法识别

c++ - snprintf : Same code - different errors/warnings on different g++ compilers

c++ - duration_cast 怎么轮

c# - 如何检索可执行文件的相对路径

c++ - 使用 log4cplus 运行代码时出现 bad_alloc 错误

类内变量的 C++ 运算符重载