- 论坛徽章:
- 2
|
本帖最后由 OwnWaterloo 于 2010-10-21 16:39 编辑
区别:
1. replace
C++提供默认的 void* operator new (size_t s);
你写了一个自己的版本, 这叫replace。
2. overload
- int max(int a, int b);
- double max(double a, double b);
复制代码 具有相同的名字, 但参数不同的函数之间互为overloaded。
根据调用处的实际参数, 决定实际调用的函数:
- max(1212, 326); // int max(int,int);
- max(12.12, 3.26); // double max(double, double);
复制代码 3. hide
上述"相同名字"有一个前提: 在一个查找的作用域内。
- namespace base
- {
- int max(int a, int b);
- }
- namespace derived
- {
- double max(double a, double b);
- }
- void test1()
- {
- using base::max;
- max(12.12, 3.26); // int max(int, int);
- // 在这个作用域里只有一个max
- // 就是int max(int, int);
- // 即使调用的实际参数是 double, double, 也只能选中这个(通过double->int的转换)
- // 不会选到derived::max
- }
- void test2()
- {
- using derived::max;
- max(1212, 326); // double max(double, double);
- // 同上, 不会选到base::max
- }
复制代码 那么:
- struct B
- {
- void f();
- };
- struct D : B
- {
- void f(int );
- };
- D d; // D确实通过继承得到B::f();
- d.f(); // 只是这个作用域里的f只有 D::f(int), 没有 B::f()。
- d.B::f(); // 显示调用通过继承得到的B::f();
复制代码 这叫hide, 派生类中的名字会隐藏基类中的名字。
使得基类的名字没有参与重载的资格。
与上面名字空间的例子类似, 可以通过using 引入基类的名字。
- struct D1 : B
- {
- void f(double);
- using B::f;
- }
- D1 d;
- d.f( ... ); // 在这里, 重载候选就有 D1::f与B::f, 根据实际参数来决议
复制代码 4. override
通过基类指针或者引用操作某个派生对象, 调用某个虚函数。
派生类可通过override, 使得该虚函数调用派生类中的版本, 而非基类中的版本。
override和overload是完全不相干的关系。
overload是编译时概念, override是运行时概念。
- struct B
- {
- virtual ~B();
- virtual void f(int );
- virtual void f(double);
- };
- void test(B* b)
- {
- // 这两个调用是由overload决议
- // 代码一旦编译完成, 就固定死了, 没得更改。
- b->f(1212); // B::f(int);
- b->f(3.26); // B::f(double);
- delete b;
- }
复制代码 运行时可以通过传入不同的B的派生类, 影响test的最终行为。
- struct D1 : B {};
- test(new D1);
- // D1没有override任何虚函数, 所以上面两个调用最终是B::f(int)和B::f(double)
复制代码
- struct D2 : B
- {
- void f(int );
- };
- test(new D2);
- // D2有override一个: B::f(int), 所以, 最终调用是 D2::f(int), B::f(double);
复制代码 如此等等。
再解释一下运行时。
上面的代码编译、链接完毕后, test的行为不能通过overload修改, 但可以通过override修改:
- #include <stdio.h>
- #include <string.h>
- int main(int argc, char* argv[])
- {
- char const* name = "D1";
- if (argc>1) name = argv[1];
- B* b = 0;
- if (strcmp(name, "D1")==0) b = new D1;
- else if (strcmp(name, "D2")==0) b = new D2;
- ...
- else
- {
- fprintf(sterr,"no derived class named %s", name);
- return -1;
- }
- test(b);
- return 0;
- }
复制代码 gcc xxx.cpp -o a.out 编译完毕后, a.out的行为依然可以修改:
a.out D1
a.out D2
大哥们, 中文很乱, 学点E文好不? |
评分
-
查看全部评分
|