2014-11-20 2 views
3

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

Я столкнулся с одной строкой, и я не уверен, как обращаться. Код использует Termios, чтобы открыть новый порт для разговора с потоком TTY и инициализирует структуру Termios, используя ключевое слово new.

termios *settings = new termios(); 

Как я понимаю, new ключевого слова, помимо выделения соответствующей памяти, вызывает инициализатор объекта. В C после выделения памяти malloc можно ли вручную вызвать инициализатор? Нужно ли мне?

У меня такое чувство, что я недопонимаю что-то очевидное/фундаментальное или что я смотрю на все это неправильно. Я не очень привык к C++-коду.

Редактировать: Я, кажется, вызвал некоторую путаницу. Строка кода выше создает новую termios-структуру, как это определено в termios.h, часть стандартных библиотек на большинстве реализаций C.

+1

«В C, после выделения памяти с помощью malloc, можно ли вручную вызвать инициализатор?» Нет, вы не можете. "Нужно ли мне?" Это зависит от объекта. – 101010

+0

Показать определение 'termios'. – Chad

+0

@Chad Вопрос заполнен C: см. Определение в manpage termios –

ответ

3

линия

termios *settings = new termios(); 

выделяет память для объекта termios и value-initializes его. Так как termios является СТРУЧОК, эквивалентный С будет

struct termios* settings = calloc(1, sizeof(*settings)); 

или

struct termios* settings = malloc(sizeof(*settings)); 
memset(settings, 0, sizeof(*settings)); 

и конечно эквивалент delete settings будет free(settings).

+0

Спасибо! «POD» означает «кусок данных», то есть «это просто структура, у нее нет инициализатора»? –

+0

@WoodrowBarlow Да, «POD» является аббревиатурой «Обычные старые данные». Любая C 'struct' будет POD в C++. ([См. Описание признака 'is_pod' в cppreference] (http://en.cppreference.com/w/cpp/types/is_pod)) – Casey

+0

Спасибо. Это отвечает именно тому, что я хотел задать в моем вопросе; Мне жаль, что я не смог выразить себя более четко. –

0

Обратите внимание, что termios это имя struct связанной с termios(3) функции, поэтому лучше не использовать, что termios в программе Linux или POSIX в C (т. Е. Избегать присвоения имен вашим типам с обычными типами, предоставляемыми системными библиотеками).

BTW вы должны рассмотреть возможность использования какой-существующий выходовспомощьютерминала библиотеку как ncurses или readline

Наконец, если вы настаиваете на иметь свой собственный termios структуру или класс (который практически очень плохая идея, выбрать какой-либо другой имя), управляемое вашей библиотекой C++, которую вызывается C, вы должны обернуть ее распределитель + конструктор & destructor + deallocator, как это.

extern "C" struct termios* make_my_termios() { 
    struct termios* ts = new termios; 
    return ts; 
} 

extern "C" void destroy_my_termios(struct termios* ts) { 
    delete ts; 
} 

И если вы просто использовать подлинный struct termios* (от termios(3)) в вашем C++ библиотеки, просто держать его, как это ...

+0

извините за путаницу. Термины, о которых идет речь, это ** ** termios, а не настраиваемая структура, которая имеет одно и то же имя (что было бы плохой идеей!). –

1

Я предлагаю создать функцию

termios *new_termios() 

, который объединит malloc с кодом конструктора. После этого не используйте malloc для размещения termios.

1

"В C, после того, как я выделить память с таНос, можно вручную вызвать инициализатор?

К сожалению, вы не можете.

Нужно ли мне?"

Это действительно зависит от определения объектов termios. В принципе, то, что делает malloc, просто выделяет кусок памяти. То есть, он не выполняет никаких инициализаций и распределений внутренней памяти, как это делает конструктор.

Что делать в таких ситуациях:

Я создаю функцию оболочки C для моих C++ объектов с помощью непрозрачных указателей. Например, чтобы вызвать конструктор в C++ объект Я хотел бы создать ++ обертка для C C в .cpp файле:

void* create_termios() { return new termios(); } 
void destroy_termios(void *obj) { delete obj; } 
// other wrapper functions for termios 

И тогда я бы интерфейс эти функции в C с .h файла:

extern "C" { 
    void* create_termios(); 
    void destroy_termios(void *obj); 
    // declare any other necessary wrappers 
} 
+0

Сделайте void * непрозрачным указателем, вместо этого –