《Effective C++》读书笔记 条款45:运用成员函数模板接受所有兼容类型

所谓智能指针是行为像指针的对象,并提供指针没有的机能。真实的指针支持隐式转换,也就是派生类指针能转换成基类指针

class Base
{
public:
	Base(){};
	~Base(){};
private:
	int b;
};
class Derived:public Base
{
public:
	Derived(){};
	~Derived(){};
private:
	int d;

};
int main()
{
	Base* pb = new Derived;//将派生类指针转换成基类指针
	return 0;
}

 

指向non_const对象的指针可以转换为 指向const对象的指针

int main()
{
	int a = 1;
	int *pa = &a;
	const int* pb= pa;
	return 0;
}

但是对于智能指针


template<typename T>
class SmartPtr{
public:
	explicit SmartPtr(T* realPtr)
	{
		count = 1;
		ptr = realPtr;
	}
	~SmartPtr()
	{
		if (--count == 0)
		{
			delete ptr;
			ptr = NULL;
		}
	}
	SmartPtr(const SmartPtr<T>& smartptr)
	{
		
		ptr = smart.ptr;
		++count;
	}
private:
	T* ptr;
	static size_t count;
};
int main()
{
	SmartPtr<Base> b_ptr = SmartPtr<Derived> (new Derived);
	return 0;
}

SmartPtr<Base> b_ptr = SmartPtr<Derived> (new Derived);这种转化是不合法的,error C2440: “初始化”: 无法从“SmartPtr<Derived>”转换为“SmartPtr<Base>”

这是因为两个SmartPtr是同一个template的不同具现体,他们之间没有什么关系。若想实现上述转变可以设法编写构造函数实现上述转换,但由于转换很多,不可能写出每一种构造函数,所以可以将构造函数写成成员函数模板

给上述智能指针的模板添加函数:template<typename U>
    SmartPtr(SmartPtr<U>& other);

该函数意味着对于任何T和任何U,可以根据SmartPtr<U>生成SmartPtr<T>,称之为泛化构造函数。之所以没有再函数前加explicit是为了效法真实指针类型之间的隐式转换。

该泛化构造函数还需要满足不允许基类指针向派生类转等行为,所以需要添加约束条件

template<typename U>
	SmartPtr(SmartPtr<U>& other) :ptr(other.getptr)
	{

	}
	T* get() const{ return ptr; }
	{
	};

上述变化是通过成员初值列,用U*指针作为初值初始化T*指针,这就要求存在U*到T*的隐式转换,正好满足真实指针的行为。该泛化的构造函数只有在实参隶属于兼容类型时才通过编译。

请记住:

1.请使用member function templates(成员函数模板)生成“可接受所有兼容类型”的函数

2.如果你声明member templates用于“泛化copy构造”或“泛化assignment操作”(此时编译器还是会生成默认的,如果没有自己写正常的),你还是需要声明正常的copy构造函数和copy   assignment操作符。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值