c++ - 在 C++ 包装器类中初始化 C 结构数据成员

标签 c++ struct initialization

基本问题基本上已经在本网站的其他地方得到解答,但我真正想要的是关于在实用性和美学方面实现我的类(class)的最佳方式的意见,以及是否涉及任何微妙之处。记住这一点,这是我的问题:

我有一个我编写的简单加密程序,现在我想向它添加 xz 压缩,它是用 C 编写的。xz 代码使用一个结构来控制进出压缩算法的数据:

/* All of this is in src/liblzma/api/lzma/base.h if you download version 5.0.3
 * XZ Utils
 */
typedef struct {
    const uint8_t *next_in;
    size_t avail_in;
    uint64_t total_in;
    /* ...
     * and so on. Some other members are enums and other structs, but
     * this is basically a POD structure
     */
} lzma_stream;

/* This macro is used to initialize lzma_stream objects */
#define LZMA_STREAM_INIT \
    { NULL, 0, 0, NULL, 0, 0, NULL, NULL, \
    NULL, NULL, NULL, NULL, 0, 0, 0, 0, \
    LZMA_RESERVED_ENUM, LZMA_RESERVED_ENUM }

/* Here's LZMA_RESERVED_ENUM in case anyone's wondering: */
typedef enum {
    LZMA_RESERVED_ENUM = 0
} lzma_reserved_enum;

我有一个 lzma_stream 的包装类,这样如果我的加密代码抛出异常,包装类析构函数可以调用函数来释放 lzma_stream 结构中分配的任何内存。所以,我有:

class Stream {
public:
    Stream();
    ~Stream();
    void init();
    // ...
private:
    lzma_stream stream_;
    // ...
};

Stream::~Stream() {
    lzma_end( &stream_ );
}

我的问题是,将如何初始化Stream::stream_,为什么?我可以单独初始化结构的成员:

Stream::Stream() : stream_(), ... {}

void Stream::init() {
    stream_.next_in = NULL;
    stream_.avail_in = 0;
    // ...
}

但我想使用 LZMA_STREAM_INIT 因为这意味着我不需要担心 xz 库中的更改。考虑到这一点,或者,我可以创建一个临时文件:

Stream::Stream() : stream_(), ... {}

void Stream::init() {
    lzma_stream const temp = LZMA_STREAM_INIT;
    stream_ = temp;
    // ...
}

初步问题:有没有一种方法可以在 Stream 构造器中进行初始化(编辑:我的意思是,在初始化列表中)? (我不这么认为,对吗?)顺便说一句,出于编译器可移植性的原因,我试图避免使用 c++0x 初始化列表。

正如我上面所说,这些是解决问题的方法,其他地方已经说过;但我想知道的是你们会用哪种方式(如果没有其他我不知道的方式)?我已经猜到你会说后一种方法,但我有一种偷偷摸摸的感觉,其中有一个陷阱:是吗?

好的,下面提供了很多有用的信息和解决方案。感谢大家的帮助。

最佳答案

是的,你可以使用ctor-initializer,你只需要添加一个辅助函数:

Stream::Stream() : stream_(def_stream) {}

static lzma_stream def_stream()
{
  lzma_stream tmpStream = LZMA_STREAM_INIT;
  return tmpStream;
}

除其他外,这允许您初始化一个 const 聚合成员。几乎所有编译器都会忽略临时文件的创建。

如果你遇到一个不支持的编译器,你可以使用这个变体:

static const lzma_stream& def_stream()
{
  static lzma_stream tmpStream = LZMA_STREAM_INIT;
  return tmpStream;
}

在 C++0x 中,您将能够编写:

Stream::Stream() : stream_ LZMA_STREAM_INIT {}

它利用了“统一初始化语法”。

关于c++ - 在 C++ 包装器类中初始化 C 结构数据成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6635981/

相关文章:

c++ - 修改const shared_ptr&传递的数据可以吗?

c++ - 创建指向函数的指针 vector

c++ - 如何计算字符串 vector ?

在c中无法将int初始化为0

c++ - ClientClass 没有命名类型。海湾合作委员会

arrays - 我可以使用什么结构来解码字符串数组的JSON数组?

C++ - 队列中的最小值

c - 从缓冲区分配不同的内存块

c++ - 如何在完成其他一些任务后在 CTOR 中初始化对象?

c - 如何初始化一个(复杂的?)结构