一个VC编译错误引发的对显示类型转换的思考(static_cast、dynamic_cast和const_cast)(四)

2014-11-24 02:21:07 · 作者: · 浏览: 9
}
void print()
{
cout<
}
};
class Point3d : public Point
{
private:
int m_z;
public:
Point3d(int x, int y, int z):Point(x, y),m_z(z){}
void print()
{
cout<
}
};
void f(Point p1, Point3d p2)
{
Point pa = static_cast(p2);
Point3d pb = static_cast(p1); // 出现error
pa.print();
pb.print();
}
int main()
{
Point p1(1, 2);
Point3d p2(1, 2, 3);
f(p1, p2);
return 0;
}
不好意思,语法检查出错了:
Point3d pb = static_cast(p1); 这一行显示:error:不存在用户定义的从Point到Point3d的转换。意思很明显,缺少转换函数,也就是copy构造函数,我们给他加上:
[cpp]
// CastExample.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include
using namespace std;
class Point
{
public:
int m_x,m_y;
public:
Point()
{
m_x = 0;
m_y = 0;
}
Point(int x, int y)
{
m_x = x;
m_y = y;
}
void print()
{
cout<
}
};
class Point3d : public Point
{
private:
int m_z;
public:
Point3d(int x, int y, int z):Point(x, y),m_z(z){}
Point3d(const Point& p) //copy 构造函数
{
m_x = p.m_x;
m_y = p.m_y;
m_z = p.m_x + p.m_y;
}
void print()
{
cout<
}
};
void f(Point p1, Point3d p2)
{
Point pa = static_cast(p2);
Point3d pb = static_cast(p1);
pa.print(); // 输出1、2
pb.print(); // 输出1、2、3
}
int main()
{
Point p1(1, 2);
Point3d p2(1, 2, 3);
f(p1, p2);
return 0;
}
运行成功,而且结果没有出现例a中的“随机值”!
这充分证明了static_cast对类类型的转换是借助copy构造函数进行的,所以在进行转换的时候需要考虑:如果类默认的copy构造函数不能实现需要的功能,需要自定义copy构造函数,这样才可以避免unsafe的情况!
(2)dynamic_cast
用法:dynamic_cast (expression)
说明:该运算符把expression转换成type-id类型的对象。
a、dynamic_cast只用于对象的指针和引用。如果type-id是类指针类型,那么expression也必须是一个指针,如果type-id是一个引用,那么expression也必须是一个引用。
b、检测在运行时进行。如果被转换的指针不是一个被请求的有效完整的对象指针,返回值为NULL.
使用场景:
a、dynamic_cast主要用于类层次间的上行转换和下行转换
在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;
在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。
b、用于类之间的交叉转换。
把上面的例a改为采用dynamic_cast 的方式,并做适当修改:
[cpp]
// CastExample.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include
using namespace std;
class Point
{
public:
int m_x,m_y;
public:
virtual void foo(){};
Point()
{
m_x = 0;
m_y = 0;
}
Point(int x, int y)
{
m_x = x;
m_y = y;
}
void print()
{
cout<
}
};
class Point3d : public Point
{
private:
int m_z;
public:
Point3d(int x, int y, int z):Point(x, y),m_z(z){}
void print()
{
cout<
}
void foo()
{
}
};
void f(Point *p1, Point3d *p2)
{
Point *pa = dynamic_cast(p2);
Point3d *pb = dynamic_cast(p1); // pb is null
if (pa)
{
pa->print();
}
if (pb)
{
pb->print();
}
}
int main()
{