重载(overload)
只能靠参数列表而不能靠函数返回值类型的不同来区分重载函数。编译器按参数列表生成不同的内部标致符
c/c++ 编译后函数名的不同
foo(int x, int y), C => _foo c++ => _foo_init_int. 那么使用 extern "C" 来解决这个差异。
note, float, double, int 作为参数的时候,可能存在隐示类型转换。
output(int x); output (float x); output(0.5)// error. output(int(0.5)); output(float(0.5));
覆盖(override)
base:: virtual , derived:: virtual // Note. on override
隐藏(跨越边界的覆盖) => 避免。
如果派生类使用了和基类同样的函数名,不管有无virtual 关键字,参数列表有无差异,基类的函数在派生类中被隐藏。调用的时候和对象指针类型相关,静态绑定。所以避免。程序需要依赖对象的真实类型。
函数默认值
函数默认值放在函数的声明中,而非定义体中
a++ vs. ++a
前置版本返回引用,后置版本返回值。 基本类型效率上差别很小,但用于用户自定义类型,尤其是大对象的时候,前置版本效率高。
Integer& operator++() {
data_++;
return *this;
}
Integer operator++(int){
integer temp=*this; // 赋值构造
data_++;
return temp; // 值传递
}
宏定义表达式用() => 考虑使用内联函数。
Note, #define MAX(i,j) (i)>(j)?(i):(j) result = MAX(i,j)+2; 就是error.; result=MAX(++i, j); 也是错误. 所以表达式最好使用内联函数。而且使用内联函数,编译器可以进行优化,也可debug.
inline
需要和函数定义体在一起。在函数声明中不生效。
类型转换
构造函数把其他类型对象转化为this对象。如果需要避免无参数的默认构造,使用explicit
同时可以把this 对象转换为其他任何类型的对象
class Point {
public:
Point(long x);
operator float() const { return fx_;)
}
Point p2(3.3)
cout << p2 << endl; // output 3.3
类型转换运算符
运算符 | 说明 |
---|---|
static_cast<dest_type>(src_obj) | 强制类型转换,编译时运行 |
const_cast | 去除一个对象的const/volatile |
reinterpret_cast<dest_type)(src_obj) | 整数转换为地址,或任何两个对象之间的转换 |
dynamic_cast<dest_type)(src_obj) | 运行时遍历类层次结构,进行转换 |