1.主函数中的两行代码都可以创建Object类型实例
class Object
{
private:
int value;
public:
Object(int x = 0) :value(x)
{
cout << "Object" << endl;
}
~Object()
{
cout << "~Object" << endl;
}
};
int main()
{
std::shared_ptr<Object> op1(new Object(10));
std::shared_ptr<Object> op2 = std::make_shared<Object>(20);
}
但是它们是有区别的,这两种方式的构建活动是不一样的
对于第一种方式来说,op1有一个ptr指针和一个删除器(mDeletor),ptr指针指向引用计数对象(RefCnt),引用计数对象有mptr指针和引用计数(ref),mptr直指向Object对象,Object对象的value域的值为10,在这个过程中在堆区的构建new了两次
对于第二种方式来说进行了一些的优化,它能够计算出Object的大小和引用计数对象的大小,直接一次开辟够Object对象和引用计数大小一样的空间,引用计数对象的mptr指针指向Object对象,在这个过程中在堆区的构建只new一次
这两种结构有什么区别呢?
在第一种方式中释放对象需要释放两次,而在第二种方式种释放对象只需要释放一次,而用第二种方式创建的对象在析构的时候也更加的复杂,需要更深入的编程
2.画出下面程序的内存分布图
class Object
{
private:
int value;
public:
Object(int x = 0) :value(x) {
cout << "Object" << endl; }
~Object() {
cout << "~Object" << endl; }
};
template<class _Ty>
class RefCnt
{
private:
_Ty* mptr;
int ref;
public:
RefCnt(_Ty* p = nullptr) :mptr(p), ref(mptr != nullptr) {
}
~RefCnt() {
}
};
template<class _Ty,class _Dx>
class my_shared_ptr
{
private:
RefCnt<_Ty>* ptr;
public:
my_shared_ptr(_Ty* p = nullptr) :ptr(nullptr)
{
if (p != nullptr)
{
ptr = new RefCnt(p);
}
}
};
int main()
{
std::shared_ptr<Object> sp1(new Object(10));
std::shared_ptr<Object> sp2;
return 0;
}
3.判断下面程序的引用计数各是多少?
class Object
{
private:
int value;
public:
Object(int x = 0) :value(x) {
cout << "Object" << endl; }
~Object() {
cout << "~Object" << endl; }
};
template<class _Ty>
class RefCnt
{
private:
_Ty* mptr;
int ref;
public:
RefCnt(_Ty* p = nullptr) :mptr(p),