boost::static_pointer_cast、boost::dynamic_pointer_castとboost::const_pointer_cast

3232 ワード

クラス階層の上下変換に裸ポインタを使用する場合はdynamic_を使用します.cast.もちろんstaticも使えますcast、dynamic_だけcastは、下り変換時(すなわちベースクラスから派生クラス)にタイプチェック機能を有し、static_castはありません.そのため、セキュリティの問題があります.
インテリジェントポインタを使用する場合、クラス階層の上下変換が必要な場合はboost::static_を使用します.pointer_castとboost::dynamic_pointer_cast.(C++11ではスマートポインタや変換もサポートされていますが、ネーミングスペースをstdに変更するだけです).
1. static_pointer_cast
#include 
#include 
#include 

using namespace std;

class CBase
{
public:
	CBase() { }
	virtual ~CBase() { }

	void myBase()
	{
		cout << "CBase::myBase" << endl;
	}
};

class CDerive : public CBase
{
public:
	CDerive() { }
	~CDerive() { }

	void myDerive()
	{
		cout << "CDerive::myDerive" << endl;
	}
};

int main(void)
{
	//     (         )
	boost::shared_ptr spDeriveUp;
	boost::shared_ptr spBaseUp;
	spDeriveUp = boost::make_shared();
	spBaseUp = boost::static_pointer_cast(spDeriveUp);
	spBaseUp->myBase();

	//     (         )      
	boost::shared_ptr spDeriveDown;
	boost::shared_ptr spBaseDown;
	spBaseDown = boost::make_shared();
	spDeriveDown = boost::static_pointer_cast(spBaseDown);
	spDeriveDown->myBase();		//     myDerive

	return 0;
}
2. dynamic_pointer_cast
#include 
#include 
#include 

using namespace std;

class CBase
{
public:
	CBase() { }
	virtual ~CBase() { }

	void myBase()
	{
		cout << "CBase::myBase" << endl;
	}
};

class CDerive : public CBase
{
public:
	CDerive() { }
	~CDerive() { }

	void myDerive()
	{
		cout << "CDerive::myDerive" << endl;
	}
};

int main(void)
{
	//     (         )
	boost::shared_ptr spDeriveUp;
	boost::shared_ptr spBaseUp;
	spDeriveUp = boost::make_shared();
	spBaseUp = boost::dynamic_pointer_cast(spDeriveUp);
	spBaseUp->myBase();

	//     (         )
	boost::shared_ptr spDeriveDown;
	boost::shared_ptr spBaseDown;
	spBaseDown = boost::make_shared();
	spDeriveDown = boost::dynamic_pointer_cast(spBaseDown);
	if (spDeriveDown == NULL)	//          ,     NULL
		cout << "spDeriveDown is null" << endl;

	return 0;
}
3. const_pointer_cast
#include 
#include 
#include 

using namespace std;

int main(void)
{
	{
		boost::shared_ptr spInt;
		boost::shared_ptr spConstInt;

		spInt = boost::make_shared(100);
		spConstInt = boost::const_pointer_cast(spInt);
		cout << "*spConstInt = " << *spConstInt << endl;
	}

	{
		boost::shared_ptr spInt;
		boost::shared_ptr spConstInt;
		//        spInt   
		spConstInt = boost::make_shared(100);
		spInt = boost::const_pointer_cast(spConstInt);
		cout << "*spInt = " << *spInt << endl;
	}


	return 0;
}