void g(char *str)
{}
void f(const char *str)
{ g(const_cast
static_cast:
可以使用static_cast来显示完成C++语言直接支持的转换。
int i = 3;
double result = static_cast
也可以使用static_cast来显示地完成用户定义构造函数或者转换例程所允许的转换。
比如:类A有一个构造函数,这个构造函数取类B的一个对象,那么可以使用static_cast把B对象转换为一个A对象。然而,在需要进行这种转换的大部分情况下,编译器都会自动完成转换。
另一种用法是在继承层次结构中完成向下类型强制转换。
class Base
{
public:
Base(){}
virtual ~Base(){}
};
class Derived:public Base
{
public:
Derived(){}
virtual ~Derived(){}
};
int main()
{
Base *b;
Derived *d = new Derived();
b = d; //会自动向上转换
d = static_cast
Base base;
Derived derived;
Base & br = base;
Derived& dr = static_cast
return 0;
}
这种类型强制转换可以应用于指针,引用,但是不能处理对象本身。static_cast这种转换也不会完成运行时类型检查。
static_cast不能直接把一种类型的指针转换为另一种无关的类型。不能使用static_cast把指针转换为int。不能使用static_cast直接把一种类型的对象转换为另一种对象。不能使用static_cast把一个const类型强制转换为非const类型。任何没有意义的转换,static_cast都做不到。
reinterpret_cast:功能比static_cast强,但安全性更低。
可以把一种类型的指针强制转换为另外一种类型的指针,即使在继承结构它们之间不相关也可以。类似的,可以把一种类型的引用强制转换为另外一种类型的引用,即使这二种引用不相关也可以。还可以把指针转换为int,或者把int转换为指针。使用reinterpret_cast时要格外小心,因为它会把原始的位解释为不同类型,而不完成任何类型检查。
dynamic_cast:使用dynamic_cast进行类型强制转换时,会在继承层次结构中对类型强制转换完成类型检查。可以使用dynamic_cast来对指针或引用进行强制类型转换。dynamic_cast会在运行时检查底层对象的运行时类型信息。如果类型强制转换没有意义,dynamic_cast会返回NULL(对指针转换),或者抛出bad_cast异常(对于引用转换)。
class Base
{
public:
Base(){}
virtual ~Base(){}
};
class Derived:public Base
{
public:
Derived(){}
virtual ~Derived(){}
};
int main()
{
Base *b;
Derived *d = new Derived();
b = d; //会自动向上转换
d = dynamic_cast
Base base;
Derived derived;
Base & br = base;
try{
Derived& dr = dynamic_cast
}catch(bad_cast&){cout<<” bad_cast!”< return 0; } 作用域解析操作符: 首先在最内层检查要访问的的名字,然后再逐渐向外,直到全局作用域。不再任何名空间、函数或者类中的名字都在全局作用域中。 有时候,一些作用域中的名字会隐藏其他作用域中同样的名字。 还有时候,你在此作用域中不是想访问默认作用域的此名字,而是想访问别的作用域同样的名字,就要使用作用域解析操作符::,为每个名字限定一个作用域。 注意:全局作用域是未命名的,所以如果要访问全局作用域中的名字,就直接单独使用::,而不需要在前面加上作用域名称。 头文件:头文件中要避免同一个文件的循环引用和多重包含。使用#ifndef机制可以用于避免循环包含和多重包含。 //logger.h #ifndef __LOGGER__ #define __LOGGER__ #include “Preferences.h” class Logger{}; #endif //__LOGGER__ 要避免头文件的这些问题,另一种做法就是超前引用。 C中实用的工具 1. 变长函数参数列表 如:print() void debugOut(char *str,...); ...表示任意数量和类型的参数。要访问这些参数,必须使用在 尽量不用此方法:因为不知道参数个数,不知道参数类型。 2. 预处理宏 #define SQUARE(x) ((x)*(x)) //注意预处理宏一定多用小括号 作为经验,尽量不用宏取代内联。很容易出错,不进行类型检查,还可能会带来调试错误(因为你编写的代码不是编译器看到的代码)。