从 extern C struct 继承时成员的初始化

Initialization of members when inheriting from extern C struct

Mixing C and C++ Code in the Same Program中给出了以下示例(此处对相关部分略作缩写)。假设 buf.h 包含以下内容:

struct buf {
    char* data;
    unsigned count;
};

// some declarations of existing C functions for handling buf...

那么推荐使用

extern "C" {
  #include "buf.h"
}

class mybuf : public buf {
public:
    mybuf() : data(0), count(0) { }

    // add new methods here (e.g. wrappers for existing C functions)...
};

为了在 C++ 中使用具有附加功能的结构。

但是,这显然会产生如下错误:

error: class `mybuf' does not have any field named `data'
error: class `mybuf' does not have any field named `count'

How can I initialize base class member variables in derived class constructor?, C++: Initialization of inherited field, and Initialize parent's protected members with initialization list (C++) 中解释了其原因。

因此,我有以下两个问题:

  1. 提供的代码是明显错误还是我遗漏了一些相关方面? (毕竟,这篇文章似乎来自一个有信誉的来源)
  2. 达到预期效果的正确方法是什么(即将 C 结构转换为 C++ class 并添加一些方便的方法,例如构造函数等)?

更新:按照建议使用聚合初始化,即

mybuf() : buf{0, 0} {}

有效,但需要 C++11。因此,我添加以下问题:

  1. 使用 C++03,有没有比使用以下构造函数更好的方法来达到预期的结果?

    mybuf() {
      data = 0;
      count = 0;
    }
    

如果您可以使用 c++11 兼容的编译器,那么这将是使用 aggregate initialization.

的初始化列表的完美用例
mybuf() : buf{0, 0}
{}

一个"correct"方法,如果你的编译器支持C++11,就是使用例如

mybuf() : buf{0, 0} {}

这与混合使用 C 和 C++ 无关。您正在尝试初始化不存在的成员;它们存在于基础 class 中是不够的。您需要初始化基地本身。

在这种情况下,使用聚合初始化:

class mybuf : public buf
{
public:
    mybuf() : buf{0, 0} {}
};
class mybuf : public buf {
public:
    mybuf();    
    // add new methods here (e.g. wrappers for existing C functions)...
};

const buf init = {0,0};

mybuf::mybuf() : buf(init) {};

会起作用。

我已经看到它可以与一些编译器一起使用,但是没有方便的标准来检查它是标准的还是扩展的。

class mybuf : public buf {
public:
    mybuf() : buf(init) { }

    // add new methods here (e.g. wrappers for existing C functions)...

    private:

    const buf init = {0,0};
};