Professional C++ CH07

Professional C++ CH07



前言

本章主要介绍类的继承相关内容


Memory Management

1.malloc & new

malloc()函数在c++中仍然存在,但应该避免使用它。new相对于malloc()的主要优点是new不只是分配内存,它还构造对象!

Foo* myFoo = (Foo*)malloc(sizeof(Foo));
Foo* myOtherFoo = new Foo();

在执行这些行之后,myFoo和myOtherFoo都将指向堆上足以容纳Foo对象的内存区域。可以使用这两个指针访问Foo的数据成员和方法。不同之处在于myFoo所指向的Foo对象不是一个正确的对象,因为它从未被构造过。malloc()函数只留出一定大小的内存。它不知道也不关心对象。相反,对new的调用分配适当的内存大小,并调用适当的构造函数来构造对象。

2.堆上和栈上的二维数组

区别:下图一目了然
在这里插入图片描述
在这里插入图片描述

3.智能指针

3.1 unique_ptr

有时候可能认为代码正确地释放动态分配的内存。不幸的是,它很可能不是在所有情况下都正确。取以下函数:

void couldBeLeaky() {
	Simple* mySimplePtr = new Simple(); mySimplePtr->go();
	delete mySimplePtr;
}

这个函数动态分配一个Simple对象,使用该对象,然后正确地调用delete。但是,在本例中仍然可能存在内存泄漏!如果go()方法抛出异常,则永远不会执行对delete的调用,从而导致内存泄漏。
在这两种情况下,都应该使用unique_ptr。对象不会被显式删除;但当unique_ptr实例超出作用域(在函数的末尾,或因为抛出了异常)时,它会自动在析构函数中释放Simple对象:

void notLeaky() {
	auto mySimpleSmartPtr = make_unique<Simple>();	//C++14
	unique_ptr<Simple> mySimpleSmartPtr(new Simple());	//C++11
	mySimpleSmartPtr->go(); 
}

这段代码使用c++ 14中的make_unique(),并结合auto关键字,这样您只需指定指针的类型,在本例中为Simple,只需指定一次。如果Simple构造函数需要参数,则将它们放在make_unique()调用的圆括号之间。

智能指针中,get()方法可用于直接访问底层指针。这对于将指针传递给需要哑指针的函数很有用。例如有以下函数:

void processData(Simple* simple) { /* Use the simple pointer... */ }
auto mySimpleSmartPtr = make_unique<Simple>(); 
processData(mySimpleSmartPtr.get());

可以释放unique_ptr的基础指针,并使用reset()将其更改为另一个指针。例如:

mySimpleSmartPtr.reset(); // Free resource and set to nullptr 
mySimpleSmartPtr.reset(new Simple()); // Free resource and set to a new
                                          // Simple instance

3.1 shared_ptr

双重删除的问题很容易引起。考虑本章前面介绍的Simple类,它在创建和销毁对象时只输出消息。如果要创建两个标准的shared_ptrs,并让它们都引用同一个Simple对象,如下所示,当它们被销毁时,两个智能指针都会尝试删除同一个对象:

void doubleDelete() {
	Simple* mySimple = new Simple(); 
	shared_ptr<Simple> smartPtr1(mySimple); 
	shared_ptr<Simple> smartPtr2(mySimple);
}
// Simple constructor called! 
// Simple destructor called! 
// Simple destructor called!

调用了两次析构函数。这在unique_ptr中也会遇到同样的问题,即使引用计数的shared_ptr类也会这样做。然而,根据c++标准,这是正确的行为。不应该像前面的doubleDelete()函数那样使用shared_ptr来创建两个指向同一个对象的shared_ptrs。相反,你应该拷贝一份如下:

void noDoubleDelete() {
	auto smartPtr1 = make_shared<Simple>();
	shared_ptr<Simple> smartPtr2(smartPtr1); 
}
// Simple constructor called! 
// Simple destructor called!

3.1 weak_ptr

weak_ptr本身也是一个模板类,但是不能直接用它来定义一个智能指针的对象,只能配合shared_ptr来使用,可以将shared_ptr的对象赋值给weak_ptr,并且这样并不会改变引用计数的值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值