Инициализация членов при наследовании от внешней структуры C

В Смешивание кода C и C ++ в одной программе приведен следующий пример (немного сокращен до соответствующих частей). Предполагать 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'

Причины этого объясняются в Как я могу инициализировать переменные-члены базового класса в конструкторе производного класса?, C ++: инициализация унаследованного поля, а также Инициализация защищенных членов родителя с помощью списка инициализации (C ++).

Таким образом, у меня есть следующие два вопроса:

  1. Код предоставлен просто неправильно или я пропускаю какой-то важный аспект? (В конце концов, статья, кажется, происходит из авторитетного источника)
  2. Как правильно достичь желаемого эффекта (т. Е. Превратить структуру C в класс C ++ и добавить некоторые удобные методы, такие как, например, конструктор и т. Д.)?

Обновить: Использование инициализации агрегации, как предложено, т.е.

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

работает, но требует C ++ 11. Поэтому я добавляю следующий вопрос:

  1. Используя C ++ 03, есть ли лучший способ достичь желаемого результата, чем следующий конструктор?

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

17

Решение

Если вы можете использовать компилятор, совместимый с c ++ 11, то это был бы идеальный вариант использования списка инициализаторов, использующего агрегатная инициализация.

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

Другие решения

Один «правильный» способ, если ваш компилятор поддерживает C ++ 11, это использовать, например,

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

Это не имеет никакого отношения к смешиванию C и C ++. Вы пытаетесь инициализировать членов, которых не существует; того, что они существуют в базовом классе, недостаточно. Вам нужно инициализировать саму базу.

В этом случае используйте агрегатную инициализацию:

class mybuf : public buf
{
public:
mybuf() : buf{0, 0} {}
};
3

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};
};
2
По вопросам рекламы [email protected]