设为首页 加入收藏

TOP

C++11模板句柄的实现:委派构造函数、default关键字分析
2015-07-20 17:39:32 来源: 作者: 【 】 浏览:3
Tags:模板 实现 委派 构造 函数 default 关键字 分析

C++11,使用委派构造函数,并且快速初始化变量,default关键字重声明默认构造函数,回复pod状态。分析与推荐用法。

目前为止,VS2012和2013对异常声明的兼容还是停留在代码沟通的级别,没有进行编译类型检查,出现如下错误可忽略。

warning C4290: 忽略 C++ 异常规范,但指示函数不是 __declspec(nothrow)


下为:VS2012不支持委托构造函数,建议使用cocos2d-x 3.2及版本的朋友更新VS至2013版。

1>d:\cpp_lab\testqueue_16th_2\testqueue_16th_2\handle.hpp(9): error C2614: “Handle ”: 非法的成员初始化:“Handle ”不是基或成员

同时VS2012也不支持快速初始化变量。

\


VS2013同时完成了对于default声明,但是如果考虑和委派构造函数一起使用的话,则会有如下的错误:

Handle() = default:Handle(p,new std::size_t(1)){};

1>d:\cpp_2013\testqueue_16th_2\testqueue_16th_2\handle.hpp(7): error C2143: 语法错误 : 缺少“;”(在“:”的前面)

编译时出现语义上的二义性。要重新定义=():()形式的语义?

原因在:一旦使用default关键字去重定义默认的构造函数使其回复至pod状态,要记得不能定义函数体,默认构造函数是由编译器合成的。若定义了default构造函数的函数体,则会出现重载定义无法识别的编译报错。

VS2013版源码如下:

class Handle
{
public:
	Handle() = default; // 不能声明函数体
	Handle(T *p = nullptr):Handle(p,new std::size_t(1))
	{
	}


	Handle(const Handle & h):Handle(h.m_pPtr,h.m_pUseCount)//委托构造函数,将先调用目标构造函数,再完成初始化
	{
		
	}

	Handle & operator = (const Handle & other);


	T & operator *() throw (std::runtime_error);
	T * operator ->() throw (std::runtime_error);

	T & operator *() const throw (std::runtime_error);
	T * operator ->() const throw (std::runtime_error);

	~Handle(void)
	{
		rem_ref();
	}

private:
	Handle(T*p,size_t * use):m_pPtr(p),m_pUseCount(use) // 目标构造函数
	{
		if (m_pPtr==nullptr)
		{
			 delete m_pUseCount;
			 m_pUseCount = nullptr;
		}
 else
 {
					++(*m_pUseCount);

 
 }
	};

	void rem_ref()
	{
		if (--*m_pUseCount == 0)
		{
			delete m_pPtr;
			delete m_pUseCount;
			m_pPtr = nullptr;
			m_pUseCount = nullptr;
		}
	}

private:
	T * m_pPtr = nullptr;//实际上这个赋值没太多意思
	size_t * m_pUseCount = nullptr;

};


template 
  
   
Handle
   
     & Handle
    
     ::operator = (const Handle
     
       & other) { ++other.m_pUseCount; rem_ref(); m_pPtr = other.m_pPtr; m_pUseCount = other.m_pUseCount; return *this; } template 
      
        inline T & Handle
       
        ::operator *() { if (m_pPtr!=nullptr) { return *m_pPtr; } else { throw std::runtime_error("dereference of unbound Handle"); } } template 
        
          inline T * Handle
         
          ::operator ->() { if (m_pPtr!=nullptr) { return m_pPtr; } else { throw std::runtime_error("dereference of unbound Handle"); } } template 
          
            inline T & Handle
           
            ::operator *() const { if (m_pPtr!=nullptr) { return *m_pPtr; } else { throw std::runtime_error("dereference of unbound Handle"); } } template 
            
              inline T * Handle
             
              ::operator ->() const { if (m_pPtr!=nullptr) { return m_pPtr; } else { throw std::runtime_error("dereference of unbound Handle"); } }
             
            
           
          
         
        
       
      
     
    
   
  

main函数:

int*p = new int(100);

	Handle
  
    pInt(p);

	Handle
   
     pInt2 = Handle
    
     (pInt); Handle
     
       pInt3 = pInt2; try { cout << *pInt << "\t" << *pInt2 << "\t" << *pInt3 << endl; } catch (runtime_error e) { cerr<
      
       
委派构造函数的使用在于内部能定义一个完整版本的构造函数,然后在类对象未完成初始化时调用该构造函数,先在当前地址完成构造。这个思维应该是以前this为非常量时代(其实我没用过非常量指针形式的this)的用法,后来新标准定义this只能为const类型,融合当前代码时长出现大量的构造函数,思考出的解决方案,不算是语法上的突破或革新。

程序结果:

?Z??http://www.2cto.com/soft下载

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇hdu 5017 Ellipsoid(西安网络赛 .. 下一篇hdu 2604 Queuing (矩阵快速幂)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·Redis 分布式锁全解 (2025-12-25 17:19:51)
·SpringBoot 整合 Red (2025-12-25 17:19:48)
·MongoDB 索引 - 菜鸟 (2025-12-25 17:19:45)
·What Is Linux (2025-12-25 16:57:17)
·Linux小白必备:超全 (2025-12-25 16:57:14)