C++类型转换方式总结 (二)

2014-11-24 12:50:49 · 作者: · 浏览: 1
, Syracuse University, ider.cs@gmail.com

///////////////////////////////////////////////////////////////////////////

#include

#include

using namespace std;

class Parents

{

public:

Parents(string n="Parent"){ name = n;}

virtual ~Parents(){}

virtual void Speak()

{

cout << "\tI am " << name << ", I love my children." << endl;

}

void Work()

{

cout << "\tI am " << name <<", I need to work for my family." << endl;;

}

/************** TryParseTo **************/

template bool TryParseTo(T** outValue)

{

T* temp = dynamic_cast (this);

if (temp == NULL) return false;

*outValue = temp;

return true;

}

protected:

string name;

};

class Children : public Parents

{

public:

Children(string n="Child"):Parents(n){ }

virtual ~Children(){}

virtual void Speak()

{

cout << "\tI am " << name << ", I love my parents." << endl;

}

/*

**Children inherit Work() method from parents,

**it could be treated like part-time job.

*/

void Study()

{

cout << "\tI am " << name << ", I need to study for future." << endl;;

}

private:

//string name; //Inherit "name" member from Parents

};

class Stranger

{

public:

Stranger(string n="stranger"){name = n;}

virtual ~Stranger(){}

void Self_Introduce()

{

cout << "\tI am a stranger" << endl;

}

void Speak()

{

//cout << "I am a stranger" << endl;

cout << "\tDo not talk to "<< name << ", who is a stranger." << endl;

}

private:

string name;

};

int main()

{

Children * parsedChild;

Parents * parsedParent;

Stranger * parsedStranger;

Parents * mother = new Parents("Mother who pretend to be a my daugher");

if(mother->TryParseTo(&parsedChild))

parsedChild->Speak();

else

cout << "Parents parse to Children failed" << endl;

delete mother;

mother = new Children("Daughter who pretend to be a my mother");

if(mother->TryParseTo(&parsedChild))

parsedChild->Speak();

else

cout << "Parents parse to Children failed" << endl;

delete mother;

Children * son = new Children("Son who pretend to be a my father");

if(son->TryParseTo(&parsedParent))

parsedParent->Speak();

else

cout << "Children parse to Parents failed" << endl;

if(son->TryParseTo(&parsedStranger))

parsedStranger->Speak();

else

cout << "Children parse to Stranger failed" << endl;

delete son;

//pointer of child class could pointer to base class object

/*

* son = new Parents("Father who pretend to be a my son");

if(son->TryParseTo(&parsedParent))

parsedParent->Speak();

else

cout << "Parse failed" << endl;

delete son;

*/

return 0;

}

/********************* Result *********************/

//Parents parse to Children failed

// I am Daughter who pretend to be a my mother, I love my parents.

// I am Son who pretend to be a my father, I love my parents.

//Children parse to Stranger failed

这段代码中使用到的类跟dynamic_cast一文中使用的基本一样,只是在基类中多了一个模板方法:

template bool TryParseTo(T** outValue)

{

T* temp = dynamic_cast (this);

if (temp == NULL) return false;

*outValue = temp;

return true;

}

该方法需要指定的目标类型,将自身指针转换成目标指针。转换成功,则将结果赋值给相应的变量,并返回真值;若失败则返回假值,不改变指针变量。因为要让外部的指针变量能够接受到改值,因此不得不使用指向指针的指针。

因为在基类中以公共结果的形式出现,所以每一个子类都继承了该方法,无论是基类的对象还是子类的对象都可以调用该方法。而该方法又不是虚方法,因此不并不希望子类去修改它。只是因为方法是模板方法,可能在编译的时候需要多花一些时间。

由于引用必须在定义时就赋值,并且dynamic_cast对于基于引用的转换不成功时将抛出异常,因此对于基于引用的转换,我还没有想出有什么好的山寨形式。

从测试代码的结果也可以看出,对于该发放的调用都是成功有效的。