参数表不相同(参数型别不同或者参数数目不同)的两个或多个函数可以构成重载函数,编译器不能通过返回类型来判断几个函数是否为重载函数
1> 参数型别不同: 注意: 这里的类别不仅指基本类型(short、int、long、char、float、double 基本类型的指针等),还包括复杂类型(父类类,各子类)(与double dispatch有关联)
2> 参数数目不同
重载函数调用的优先级如下:
1> 准确匹配,实参类型与形参类型完全匹配。
2> 类型提升,比如 bool to int, int to unsigned int (指针类型没有类型提升一说,bool * 和int * 始终是不同类型,这在理解static_cast, reinterprete_cast不同时是一样的)
例:
void fun(int); // bool b; fun(b); 编译通过
void fun(bool); // int i; fun(i); 编译error
void fun(int*); // bool b; fun(&b); 编译error
3> 标准类型转换,比如 int to double, double to int, 子类提升为父类
例:
void fun(double); // int b; fun(b); 编译通过
void fun(int); // double i; fun(i); 编译通过
4> 用户自定义转换 // 待解
5> 不定数量形参(...) // 待解
class A { };
class AA : public A {}
class B {
public:
void fun(A& a) {}
void fun(AA& a1) {}
};
int main(void)
{
A* a = new A;
A* a1 = new AA;
AA* aa = new AA;
B b;
b.fun(*a); // 会调用 void fun(A& a) {}
b.fun(*a1); // 会调用 void fun(A& a) {} 这就是单dispatch,无法识别a1真正的类型,c++不支持double dispathc
b.fun(*aa); // 会调用 void fun(AA& a) {} // aa是AA类的实例。
}
2. Double Dispatch(双分派)
visitor模式采用了Double Dispatch方式
双分派就是根据运行时多个对象的类型确定方法调用的过程。c++语言只支持静态多分派和动态的单分派,但是可以利用设计模式可以实现Double Dispatch
静态分派(Static Dispatch,静态多态---重载),发生在编译时期,分派是根据静态类型信息发生的,方法重载就是静态分派
动态分派(Dynamic Dispatch,动态多态---虚函数),发生在运行时期,动态分派动态地置换掉某个方法
举例: 对vector<A *>排序, 每个A子类对象都要实现compare函数,用于this和另一个对象的比较
class A {
public:
virtual bool compare(A* a) = 0;
}
此时, 每个子类的compare函数里都需要switch case来判断到底和哪种子类对象进行比较,这就是一种Double Dispatch。
改进:使用子类重载来消除switch case,父类也需要改进。
class A {
public:
bool compare(A* a) { a->compare(*this); } // *this取得了子类对象 动态多态
virtual
}
class A1 : public A {
public:
virtual bool compare(A2& a) { ,,. } // 静态多态
}
class A2 : public A {
public:
virtual bool compare(A1& a) { ,,. } // 静态多态
}
这里假设只有A1和A2两个子类,如果再加一个子类A3,则A1 A2子类中都要增加一个compare函数virtual bool compare(A3& a) ,用于和新增对象的比较。这也是visitor模式最主要的缺点
参考:
http://blog.csdn.net/seizef/article/details/5332297
http://blog.163.com/very_fyy/blog/static/22521685201063044030549/