假设我有一个自动锁类,它看起来像这样:
template <T>
class autolocker {
public:
autolocker(T *l) : lock(l) {
lock->lock();
}
~autolocker() {
lock->unlock();
}
private:
autolocker(const autolocker&);
autolocker& operator=(const autolocker&);
private:
T *lock;
};
显然,目标是能够将此自动锁定器与任何具有锁定/解锁方法的东西一起使用,而无需诉诸虚拟函数。
目前,它的使用方式很简单:
autolocker<some_lock_t> lock(&my_lock); // my_lock is of type "some_lock_t"
但这样做是违法的:
autolocker lock(&my_lock); // this would be ideal
无论如何,有没有模板类型推导可以很好地发挥作用(保留在我的自动储物柜中是不可复制的)。或者只是指定类型最简单?
是的,您可以使用范围保护技术
struct autolocker_base {
autolocker_base() { }
protected:
// ensure users can't copy-as it
autolocker_base(autolocker_base const&)
{ }
autolocker_base &operator=(autolocker_base const&)
{ return *this; }
};
template <T>
class autolocker : public autolocker_base {
public:
autolocker(T *l) : lock(l) {
lock->lock();
}
autolocker(const autolocker& o)
:autolocker_base(o), lock(o.lock)
{ o.lock = 0; }
~autolocker() {
if(lock)
lock->unlock();
}
private:
autolocker& operator=(const autolocker&);
private:
mutable T *lock;
};
然后编写一个创建自动锁的函数
template<typename T>
autolocker<T> makelocker(T *l) {
return autolocker<T>(l);
}
typedef autolocker_base const& autolocker_t;
然后你可以这样写:
autolocker_t lock = makelocker(&my_lock);
一旦 const 引用超出范围,就会调用析构函数。它不需要是虚拟的。至少海湾合作委员会很好地优化了这一点 https://stackoverflow.com/questions/2419650/c-c-macro-template-blackmagic-to-generate-unique-name/2419715#2419715.
遗憾的是,这意味着您必须使您的储物柜对象可复制,因为您需要从生成器函数返回它。但是旧对象不会尝试解锁两次,因为它的指针在复制时被设置为0,所以它是安全的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)