[C++]Warning C4150小议

本文探讨了C++中因不完整类型导致的内存管理问题,包括内存泄漏和资源未释放等后果,并提供了几种解决方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、体现

0.代码:

class A;
class B
{
public:
	//构造函数在其它文件中
	B(void);			
	~B(void)
	{
		//如果A中还有堆开辟,那么会有内存泄漏
		delete m_pA;	
	}
	A* m_pA;
};

1.警告:

warning C4150: 删除指向不完整“Base”类型的指针;没有调用析构函数

2.解释

(1)Foreward declaration

使用前置声明(Foreward declaration)来声明class A,此时class A并没有完整的定义,表现为其后面的类只能申明其指针,或者引用,前置声明以后的类无法看到其类实体。一般使用一些智能指针的时候也会出现这个问题。

(2)Incomplete Type

由于A是Incomplete Type(不完整类型),编译器只是把A加入到符号表并标记A为一个class,编译器并不知道更多的信息,比如A的大小,有何成员函数等等。编译器也无法知道A所对应的析构函数(destructor),因此不会调用A的析构函数。

(3)delete

在调用delete来删除pA的时候,编译器可以知道pA所指的内存大小,因为内存分配器在内存块中保存了大小信息,可以正确释放A所占据的内存,此时的delete相当于free()。注意,但是如果是A在堆上开辟的内存(比如在构造函数中),那么这些内存将被保留。也就是说,如果A没有再在堆上开辟内存,那么也不会有内存泄漏。

三、后果

1.可能内存泄露

2.伴随的资源没有释放

四、解决方案

1.移进来A的头文件,去除A的Foreward declaration

2.如果考虑1可能带来的依赖,可将(delete pA)放到cpp中实现,在cpp中引入头文件,如果担心效率,可再放到nil的内联文件中

3.网上有人说:如果在其它地方调用了析构函数,那么可以用

delete (void *)pA;

删除内存。

猜想,这个可能只有Placement new的时候才有可能用到这种情况。

五、总结

视警告如错误,勿以恶小而为之 勿以善小而不为。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值