c++第24节课(C++课程总览)__2018.06.10

智能指针:多线程访问共享对象。

强弱智能指针。

智能指针使用在多线程环境中。

强烈推荐一本书《Linux多线程服务端编程module网络库》看第一章。

编写线程安全的类。

竞态条件。由于CPU调用顺序不同,结果不同。

内存:数据段、堆、栈。多线程共享的是数据的和堆。栈是每个线程所私有的。

线程的运行可以看做并发的运行。

运行结果不可预期。

多线程环境中,操作共享对象。在访问共享对象的时候,另外的线程可能正在析构或已经析构完成。

解决办法?

怎样在多线程环境下,安全的访问共享对象?

在创建的时候,使用强智能指针持有,其他线程使用弱智能指针持有。

到处使用强智能指针会发生交叉引用。

share_ptr<A> ptr1(new A());:(定义处)

week_ptr<A> pw=>obj;

share_ptr<A> sp=pw.lock();引用计数的操作时原子操作。(弱智能指针的提升)

智能指针出作用域前会被析构掉。

包含系统的头文件,相当于你在搞系统开发呢。

#include <windows.h>

包含了创建线程的方法。

不传参数就写NULL。

线程创建了对象。

sleep的单位是毫秒。

公司里面写东西必须先写文档,理清思路。

堆上的资源是共享的。

多线程访问共享对象。

class Test
{
public:
	Test(){ cout << "Test()" << endl; }
	~Test(){ cout << "~Test()" << endl; }
	void test(){ cout << "call Test::test" << endl; }
};

//线程参数的结构体类型
struct ThreadData
{
	ThreadData(shared_ptr<Test> sp) :wp(sp){}
	weak_ptr<Test> wp;
};

//子线程
DWORD WINAPI threadProc(void *lparg)
{
	::Sleep(2000);

	ThreadData *p = (ThreadData*)lparg;
	//p->test();

	//通过weak智能指针的提升,来检测共享对象的存活状态
	shared_ptr<Test> sp = p->wp.lock();
	if (sp != NULL)
	{
		cout << "提升成功了!" << endl;
		sp->test();
	} 
	else
	{
		cout << "提升失败了" << endl;
	}

	delete p;

	return 0;
}

void func()
{
	//Test *p = new Test();
	shared_ptr<Test> sp(new Test());
	cout << sp.use_count() << endl;

	ThreadData *data = new ThreadData(sp);
	//创建一个线程  类似pthread_create
	::CreateThread(NULL, 0, threadProc, data, 0, NULL);

	//::Sleep(2000);

	//delete p;
	//::Sleep(5000);
}
int main()
{
	func();

	::Sleep(5000);

	return 0;
}

内存池的开发在底层开发中,是很重要的一部分。

空间配置器,给了三篇博客,下去好好看。

小块内存频繁使用,用内存池进行处理。

大块内存知己用malloc和free。

SGI STL内存池。以8的倍数进行增长。

空间配置器:分配内存、释放内存、构造对象、析构对象。

栈上的对象不管是正常结束还是异常结束,出作用域一定会析构。

静态链表,每个节点的内存都是连续的。

每个节点(chunk)的前4个节点记录了下一个节点的内存起始地址。


多核,做到真真正正的并发。

用通俗的语言把复杂的问题解释清楚。

class默认是私有继承。struct默认是共有继承。

在c语言中,空struct是0,c++中是1.

面试不要跟考试一样。

在c++和C语言中,编译器生成符号的方式不同,所以必须在,调用时告诉他,以什么符号去找符号。

面试的时候要有自信,不要想那么多,要了要不要算了。

析构函数写成虚析构函数。虚函数就得去虚函数表中去找。

栈上的对象出作用域,自己进行析构。

基类指针指向堆上的派生类对象。就得写成虚函数。派生类析构自己的基类成员对象时会去调用基类的析构函数。这样就会导致派生类对象的析构函数调用不到,会导致资源泄漏。这种情况下就应该写成虚函数。

运行时的绑定是多态的基础。

哈希表的增删查效率非常高。

连续删除、插入迭代器会失效。如何防止,insert和esaear返回迭代器类型。

c++This指针是干什么用的:指向自身。方法就是靠this指针区分不同对象的方法。

基类对象的成员函数,全部写成纯虚函数。基类不想让它实例化。纯虚函数不能实例化。运行时纯虚函数表都保留着只读数据段中。

静态函数不能写成虚函数。

当内联(只是对编译器的建议)函数被修饰成虚函数,就不会内联。

函数的调用链。

抛出异常。

catch();用来接收、处理异常。

出了作用域,在哪里都找不到局部作用域中的变量。

智能指针可以帮你保证资源的释放,不会发生资源泄漏。

try{(可能发生异常的代码)

代码1:

代码2:

}

catch(string ***)

{

}

异常是可以抛的,一级一级的往上抛。

如何防止内存泄漏:智能指针。

dqueue,图画的非常好。deque源码完整分析(带图例)

 http://blog.csdn.net/u013074465/article/details/44617629 

重点在容器、智能指针那块。

new和malloc有什么区别?

运算符,因为它确实不是一个函数。它们的执行都会调用一个运算符的重载函数。

new的底层也是调用malloc。

void *:释放的内存和类型无关。

库都是动态链接的。如果你自己提供了new和delete的运算符的重载函数。它就会调用你自己的运算符重载函数,而不去链接库中的。

free不需要指定长度,长度在内存块中记录着。

4个字节记录对象的个数。

开辟单个对象不用记录对象的个数。

构造函数、析构函数的都有this指针,它要知道自己关联的是哪个对象。

都没有从正确的地方开始释放。

当自定义类,并提供了析构函数,则delete ptr;和delete []ptr;不能混用。

编译器的实现者。

int *p=new int;

用拿到的p并不是底层真真正正开辟的内存的起始地址,它返回的是,对象的起始地址。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值