POCO::Foundation 内存管理(一) AutoPtr

引用计数:

1.无论何时一个引用被销毁或重写,它所引用的对象的引用计数减少。

2.无论何时一个引用被创建或拷贝,它所引用的对象的引用计数增加。

3.初始时的引用计数是1

4.当一个对象的引用计数为0时,这个对象资源被销毁。

5.在多线程环境下,增加和减少操作必须是原子的操作。

对象拥有权:

1.如果某人拥有一个对象的拥有权,那么他有责任在对象不需要的时候删除这个对象。

2.如果对象的拥有者销毁资源失败,那么就会导致一个内存漏失。

3.其他人也可以指向这个对象,但是,他们绝不销毁这个对象。

4.拥有权是可以转移的,但是,在任何一个给定的时刻,仅有一个拥有者。

二者关系:

1.一个拥有有引用计数性质的对象的指针不将增加这个引用的引用计数。

2.这说明没有先前的拥有者,换句话说,这个对象刚刚被创建。

3.或者先前的拥有者放弃了拥有权,因此他也不减少所持有对象的引用计数。

4.通常,第一个在对象创建后被对象赋值的指针拥有拥有权,其他的则不。

AutoPtr类模板:

1.Poco::AutoPtr实现了一个引用计数的智能指针。

2.Poco::AutoPtr可以被任何支持引用计数特性的类实例化。

3.一个支持引用计数的类必须含有下列特性:

              1.维持一个引用计数,初始的时候为1.

              2.实现一个方法void duplicate()用来增加引用计数。

              3.实现一个方法void release()用来减少引用计数,当引用计数为0时,销毁资源。

AutoPtr构造和赋值:

1.当从一个C*构造AutoPtr<C>,AutoPtr拥有C的拥有权,引用计数不变。

2.当赋值一个C*AutoPtr<C>AutoPtr拥有C的拥有权,引用计数不变。

3.当从另外一个AutoPtr<C>构造AutoPtr<C>,这两个AutoPtr共享C的拥有权,引用计数增加。

4.当赋值另一个AutoPtr<C>AutoPtr<C>,这两个AutoPtr共享C的拥有权,引用计数增加。

class RCO
{
public:
	RCO(): _rc(1)
	{}
	void duplicate()
	{
		++_rc; // Warning: not thread safe!
	}
	void release()
	{
		if (--_rc == 0) delete this; // Warning: not thread safe!
	}
private:
	int _rc;
};

这个类实现了两个方法,所以支持引用计数了。

int main(int argc, char** argv)
{
	RCO* pNew = new RCO; // _rc == 1,构造的时候_rc 为1 
	AutoPtr<RCO> p1(pNew); // _rc == 1,从一个C*构造AutoPtr<C>
	AutoPtr<RCO> p2(p1); // _rc == 2,从另外一个AutoPtr<C>构造AutoPtr<C>
	AutoPtr<RCO> p3(pNew, true); // _rc == 3,从另外一个AutoPtr<C>构造AutoPtr<C>
	p2 = 0; // _rc == 2,将这个AutoPtr对象赋值为0,就说明它放弃引用,应用计数减一
	p3 = 0; // _rc == 1,同上
	RCO* pRCO = p1; // _rc == 1,
	p1 = 0; // _rc == 0 -> deleted,放弃引用,此时_rc为0,销毁资源
	// pRCO and pNew now invalid!
	p1 = new RCO; // _rc == 1,
	system("pause");
	return 0;
}

AutoPtr操作和语义:

1.Poco::AutoPtr支持相关的操作:==,!=,<,<=,>,>=

2.当进行解引用操作:*,->,如果指针为空,抛出NullpointerException异常。

3.Poco::AutoPtr支持完全的值操作相关语义:默认构造函数,拷贝构造函数,赋值,它也可以被用在集合:std::vector等中。

4.使用AutoPtr::isNull()或者AutoPtr::operator !()测试是否指针为空。

RefCountedObject:

1.Poco::RefCountedObject实现了一个线程安全的引用计数功能,它使用平台相关的原子操作。

2.可以用来作为想实现引用计数功能类的基类。

3.Poco::RefCountedObject有一个保护的析构函数

4. 所有的引用计数对象应该有一个保护的析构函数,以免显示的 delete 操作发生。
class RCO: public RefCountedObject
{
public:
RCO()
{}
void greet() const
{
std::cout << "Hello, world!" << std::endl;
}
protected:
~RCO()
{}
};

继承RefCountedObject的类拥有引用计数的功能。

int main(int argc, char** argv)
{
AutoPtr<RCO> pRCO(new RCO);
pRCO->greet(); // AutoPtr has -> operator
(*pRCO).greet(); // AutoPtr has * operator
std::cout << "refcount: " << pRCO->referenceCount() << std::endl;
RCO* p1 = pRCO; // AutoPtr supports conversion to plain pointer
RCO* p2 = pRCO.get();
return 0;
}

AutoPtr和类型转换:

1.就像普通的指针,AutoPtr支持类型转换操作。

2.template<class Other> AutoPtr<Other>cast() const

3.AutoPtr 之间的转换总是类型安全的,因为它内部使用dynamic_cast。

class A: public Poco::RefCountedObject {};
class B: public A {};
class C: public Poco::RefCountedObject {};//A,B,C都是支持引用计数功能的类
int main(int argc, char** argv)
{
Poco::AutoPtr<A> pA;
Poco::AutoPtr<B> pB(new B);
pA = pB; // okay, pB is a subclass of pA
pA = new B;
// pB = pA; // will not compile
pB = pA.cast<B>(); // okay
Poco::AutoPtr<C> pC(new C);
pA = pC.cast<A>(); // pA is null,C类和A类无继承关系,内部使用dynamic_cast返回为0
return 0;
}

这就是AutoPtr的一些基本性质,不妥之处,还望指出。

谢谢观赏!




你可能感兴趣的:(thread,多线程,c,vector,delete,Class)