C++中非POD结构体继承POD结构体是否属于未定义行为?
继承C结构体在C++中使用是否会导致未定义行为?
我正在使用一个C兼容库,该库声明了如下结构体:
typedef struct _gsk_oid { int count; gsk_uint32 * elements; } gsk_oid;
无法修改该库,因此在C++中定义了继承自gsk_oid的oidX结构体,使其可作为gsk_oid使用,同时拥有构造函数以便在代码中创建OID,定义如下:
struct oidX : public gsk_oid { oidX(int countX, gsk_uint32 first, ...); oidX(const gsk_oid *inOID); ~oidX(); };
例如可以编写oidX testOID1(9, 1, 3, 6, 1, 5, 5, 7, 48, 1);这样的代码,并在需要gsk_oid的上下文使用testOID1。目前出现了无法解释的异常结果,想请教这种写法是否会导致未定义行为?
这种写法本身不会直接导致未定义行为,但你的实现细节很可能存在问题,进而引发异常。以下是关键分析点:
公共继承的兼容性:C++标准保证,公共继承自标准布局类型(这里的
gsk_oid是C结构体,属于标准布局类型)的oidX,其内存布局的起始部分与基类gsk_oid完全一致。这意味着你可以安全地将oidX*隐式转换为gsk_oid*,或把oidX对象当作gsk_oid传递给C库函数,这部分是符合规范的。潜在的风险点:
- 可变参数构造函数的实现问题:你第一个构造函数用了
...可变参数,若在实现中没有正确读取countX个参数、或没有为elements分配足够的内存、或内存分配后没有正确拷贝参数值,会直接导致内存越界、野指针等问题,这是最常见的异常诱因。 - 析构函数的内存管理冲突:如果
gsk_oid的elements内存是由C库分配的(比如库函数返回的OID),而你的~oidX()析构函数直接用delete[]释放了这块内存,就会引发双重释放或释放不属于自己的内存的问题;反之,如果是oidX自己分配的内存,却被C库函数尝试释放,也会导致异常。 - 对象切片问题:虽然你是用
oidX作为gsk_oid使用,但如果存在把oidX对象按值传递给接收gsk_oid的函数的情况,会发生对象切片——只拷贝基类部分,不过这里oidX没有额外成员,所以主要风险还是集中在内存管理层面。
- 可变参数构造函数的实现问题:你第一个构造函数用了
总结:继承本身没问题,异常大概率出在构造函数、析构函数的内存实现细节上,建议重点检查elements的内存分配、拷贝、释放逻辑是否自洽,以及与C库的内存管理规则是否兼容。
内容的提问来源于stack exchange,提问作者Charles
相关产品推荐
相关产品推荐

