Рассмотрим программу со смешанным кодом C и C ++.Часть C ++ содержит класс, который динамически выделяет стиль C typedef struct
.Минимальный пример:
obj.h (код C)
typedef struct _Ctype {
int i;
} Ctype;
class.hpp (код C ++)
struct A {
struct _Ctype *x;
A(int i);
~A();
};
class.cpp (код C ++)
#include "class.hpp"
extern "C" {
#include "obj.h"
}
A::A(int i)
{
x = new struct _Ctype;
x->i = i;
}
A::~A()
{
delete(x);
}
main.cpp (код C ++, основная программа)
#include "class.hpp"
int main()
{
A a(3);
return 0;
}
(Обоснование для этого дизайна исходит из этого ответа )
Безопасно ли (то есть, нет UB) использовать выражение new
для выделения типа стиля C struct _Ctype
, как в приведенном выше коде, или лучше использовать C-стиль malloc
/ free
?
class.cpp (код C ++, альтернатива)
#include <cstdlib>
#include "class.hpp"
extern "C" {
#include "obj.h"
}
A::A(int i)
{
x = (struct _Ctype *)malloc(sizeof(struct _Ctype));
x->i = i;
}
A::~A()
{
free(x);
}
ADDITION
Чтобы прояснить вопрос после некоторых комментариев ниже: В приведенном ниже минимальном примере весь код компилируется с помощью компилятора C ++.Однако можно подумать об использовании кода C ++ вместе с библиотекой C.Затем вопрос можно переформулировать следующим образом:
- Если я выделю память для стиля C
typedef struct
с помощью кода C ++, сможет ли библиотека C безопасно использовать выделенную переменную?Если да, безопасны ли оба приведенных выше варианта?
Обратите внимание, что можно также подумать о выделении памяти для Ctype
через функцию C, чтобы код C ++ управлял только указателем на нее.Например:
obj.h (C-код)
typedef struct _Ctype {
int i;
} Ctype;
Ctype *allocate_Ctype();
void deallocate_Ctype(Ctype* p);
obj.C (C-код)
#include <stdlib.h>
#include "obj.h"
Ctype *allocate_Ctype()
{
return (Ctype *)malloc(sizeof(Ctype));
}
void deallocate_Ctype(Ctype *p)
{
free(p);
}
class.cpp (код C ++)
#include "class.hpp"
extern "C" {
#include "obj.h"
}
A::A(int i)
{
x = allocate_Ctype();
x->i = i;
}
A::~A()
{
deallocate_Ctype(x);
}
(Примечание: конечно, необходимо правильно определить конструктор копирования и назначение оператора класса A, кодслужит иллюстрацией вопроса)