2010-01-03 2 views
3

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

Я могу использовать списки инициализации в точке объявления переменных; однако это не так полезно, если все аргументы неизвестны во время компиляции или если я не объявляю локальный/глобальный экземпляр, например:

Код Legacy C, который объявляет структуру, а также использует API это

typedef struct 
{ 
    int x, y, z; 
} MyStruct; 

C++ код с использованием библиотеки C

void doSomething(std::vector<MyStruct> &items) 
{ 
    items.push_back(MyStruct(5,rand()%100,items.size()));//doesn't work because there is no such constructor 
    items.push_back({5,rand()%100,items.size()});//not allowed either 

    //works, but much more to write... 
    MyStruct v; 
    v.x = 5; 
    v.y = rand()%100; 
    v.z = items.size(); 
    items.push_back(v); 
} 

Создание локальных экземпляров, а затем установка каждого члена по одному (myStruct.x = 5; и т.д.) реальная боль, и довольно трудно читать при попытке добавить в контейнер 20 разных предметов ...

+3

Вы ищете решение на C или C++? – Christoph

ответ

7

Если вы не можете добавить конструктор (который является лучшим решением в C++ 03, но вы, вероятно, имеют ограничение на совместимость с C), вы можете написать функцию с тем же эффектом:

MyStruct makeAMyStruct(int x, int y, int z) 
{ 
    MyStruct result = { x, y, z }; 
    return result; 
} 

items.push_back(makeAMyStruct(5,rand()%100,items.size())); 

Edit: я бы проверил теперь, что C++ 0x предлагает что-то для этой точной задачи:

items.push_back(MyStruct{5,rand()%100,items.size()}); 

, которая доступна в г ++ 4.4 ,

+0

+1: Я думаю, что это ответ, который он ищет – Christoph

+0

Кстати: почему бы не использовать список инициализации? – Christoph

+0

Нет веской причины, я изменю свою функцию. – AProgrammer

7

Вы ищете C99 сложные литералы. Пример кода:

struct foo *foo = malloc(sizeof *foo); 
*foo = (struct foo){ bar, baz }; 
+0

Звучит как отличное решение, если оно было поддержано компилятором (VC++ 9) :( –

+2

на этот раз, это на самом деле не ошибка компилятора, поскольку сложные литералы - это функция C99, не поддерживаемая C++, я неправильно прочитал ваш вопрос и подумал, что вы искали решение в C ... – Christoph

+0

см. http://stackoverflow.com/questions/1705147/struct-initialization-of-the-cc-programming-language/1705166#1705166 для некоторых объяснений и C++ 0x Синтаксис – Christoph

3

Как насчет:

MyStruct v = {5, rand()%100, items.size()}; 
items.push_back(v); 
+0

Итак, чтобы сделать несколько вещей, которые вам нужно делать v1, v2, v3, v4 и т. Д., Невозможно повторно использовать один локальный? –

+0

Если у вас есть v1, v2, v3 и v4, вы застряли в записи чего-то 4 раза - если только вы не хотите, чтобы они имели одинаковое значение, и в этом случае вы можете выполнять простые задания, конечно. Если у вас есть v [0], v [1], v [2], v [3] и v [4], тогда вы можете использовать цикл. –

+0

Я не уверен на 100%, но думаю: MyStruct vs [2] = {{1, 2, 3}, {2, 3, 4}}; будет работать – James

2

Не ясно, что вы просите. В C++, очевидное решение, чтобы дать STRUCT конструктор:

struct MyStruct { 
    int x, y, z; 
    MyStruct(int ax, int ay, int az) : x(ax), y(ay), z(az) {} 
}; 
+0

он ищет решение в C – Christoph

+0

Он помечен C++, хотя – James

+0

Тогда почему он отметил его на C++? Вот почему я сказал, что я не знаю. –

2

Создайте функцию для ее инициализации, аналогичную конструктору C++.

+0

(+1) Ответ KISS со всех точек зрения. –

1

Другим вариантом является вывод из структуры и добавление туда конструктора.

struct MyDerivedStruct : public MyStruct 
{ 
    MyDerivedStruct(int xi, int yi, int zi) 
    { 
     x = xi; 
     y = yi; 
     z = zi; 
    } 
} 

Тогда вы можете использовать этот производный тип в своем собственном коде и передать его в библиотеку C, когда это необходимо. Язык должен позаботиться о неявном преобразовании в MyStruct, если это необходимо.

В качестве бонуса вы также можете добавить другие полезные функции-члены, возможно даже упаковывая многие из унаследованных функций C, которые используют этот тип.

Смежные вопросы