c ++中动态大小的类

use*_*918 5 c++ dynamic-memory-allocation

我想创建一个Word包含一个单词的类.我将为字典中的每个单词都有一个类的实例(所以很多) - 不,我不能使用树结构来存储我的特定应用程序.当然,字符串的大小可能会有所不同,我不想杀死内存.我想在课堂上这样做,如下:

class Word {
    public:
        ...
    private:
        int         len;
        LetterData  letters[];
};
Run Code Online (Sandbox Code Playgroud)

然后使用以下命令动态分配Word:

Word *pNewWord = malloc(sizeof(Word)+sizeof(LetterData)*len);   
Run Code Online (Sandbox Code Playgroud)

我意识到这不是很C++'ish.所以我的问题是:首先,有没有更好的方法来做到这一点,如果没有,这会导致问题吗?Word不会继承任何其他类类型(我很确定继承会杀死这个......).

注意:内存使用和速度非常重要 - 我想避免每个字的额外指针,我想避免每次访问额外的指针deference ...

Bat*_*eba 5

我的出发点是构建现在的内容,而不仅仅是代理类std::string:

class Word
{
public:
    std::size_t getSize() const; // in place of your 'len' member.

private:
    std::string m_data;
};
Run Code Online (Sandbox Code Playgroud)

然后,我会构建我的程序的其余部分,然后才能在我的Word类cf中出现性能问题.程序的其他方面我会尝试重构它,用m_data其他东西代替.

我的钱是不必要的,你对C++标准库对象的怀疑没有足够的性能没有根据.


San*_*dro 5

使用开放大小的数组作为结构体的最后一个成员在 C 中是很常见的做法。它在 C99 中被标准化(2.6.7.“灵活数组成员”)。

C++ 标准没有提及“灵活数组成员”。所以不能保证它在 C++ 中工作。但是大多数流行的编译器甚至对 C++ 也支持此功能:

所以实际上可以使用它,但这是非常危险的做法。你应该尽量避免它,如果你决定使用它,你需要非常小心。

如果您使用这种技术,有几个潜在的问题:

  • 内存缓冲区的任何重新分配或删除都会使您的对象无效。
  • 您的课程必须是不可复制的。任何副本(通常是将对象作为参数传递时的隐式副本)都会使对象无效。您必须禁止复制构造函数和赋值运算符。
  • 继承是不可能的,你必须禁止它。
  • 您应该正确初始化所有数据以避免垃圾(可能用零填充缓冲区而不是使用放置新运算符)
  • 此方法常用于序列化、保存和恢复对象,但不可移植。您需要考虑成员和大/小端的大小。

因此,如果可能的话,最好使用其他东西。例如,将 LetterData 向量作为类成员的解决方案。