只有多态
#include <iostream>
class Base {
public:
virtual void f(double){ std::cout << "Base::Double!" << std::endl; }
//virtual void f(int) { std::cout << "Base::Int!" << std::endl; } // (1)
virtual ~Base() {}
};
class Derived : public Base {
public:
//using Base::f; // (2)
void f(double) { std::cout << "Derived::Double!" << std::endl; } // (3)
};
int main(int, char **) {
Derived d;
d.f(21); //Derived::Double!
d.f(1.1); //Derived::Double!
Base* p = &d;
p->f(21); //Derived::Double!
p->f(0.1); //Derived::Double!
return 0;
}
这是一个典型的多态的例子
继承默认不能重载父类函数
如果注释(1),代码变为:
#include <iostream>
class Base {
public:
virtual void f(double){ std::cout << "Base::Double!" << std::endl; }
virtual void f(int) { std::cout << "Base::Int!" << std::endl; } // (1)
virtual ~Base() {}
};
class Derived : public Base {
public:
//using Base::f; // (2)
void f(double) { std::cout << "Derived::Double!" << std::endl; } // (3)
};
int main(int, char **) {
Derived d;
d.f(21); //Derived::Double!
d.f(1.1); //Derived::Double!
Base* p = &d;
p->f(21); //Base::Int!
p->f(0.1); //Derived::Double!
return 0;
}
前两个输出结果是因为,此时派生类的 f(double) 遮蔽(hide)了基类的两个函数。这是因为编译器在基类的作用域发现了一个 f,就不会向上沿着继承树寻找重载。
后两个输出结果是因为此时多态任然存在,此时虚函数表为:
| Base | Derived |
|---|---|
| Base::f(double) | Derived::f(double) |
| Base::f(int) | Base::f(int) |
因此p->f(21)会调用父类的函数Base::f(int)
如果我们把 (3) 也注释了,代码将变为:
#include <iostream>
class Base {
public:
virtual void f(double){ std::cout << "Base::Double!" << std::endl; }
virtual void f(int) { std::cout << "Base::Int!" << std::endl; } // (1)
virtual ~Base() {}
};
class Derived : public Base {
public:
// using Base::f; // (2)
// void f(double) { std::cout << "Derived::Double!" << std::endl; } // (3)
};
int main(int, char **) {
Derived d;
d.f(21); //Base::Int!
d.f(1.1); //Base::Double!
Base* p = &d;
p->f(21); //Base::Int!
p->f(0.1); //Base::Double!
return 0;
}
这是因为子类没有 f 函数,编译器就会向上寻找父类,发现父类有 2 个 f,就构成了重载
如果想要重载父类函数,有两种办法:
手动重载
class Base {
public:
virtual void f(double){ std::cout << "Base::Double!" << std::endl; }
virtual void f(int) { std::cout << "Base::Int!" << std::endl; }
virtual ~Base() {}
};
class Derived : public Base {
public:
void f(int a) { Base::f(a); }
void f(double) { std::cout << "Derived::Double!" << std::endl; }
};
这很麻烦,后来 C++ 委员会增加了 using 关键词,如下:
using
#include <iostream>
class Base {
public:
virtual void f(double){ std::cout << "Base::Double!" << std::endl; }
virtual void f(int) { std::cout << "Base::Int!" << std::endl; } // (1)
virtual ~Base() {}
};
class Derived : public Base {
public:
using Base::f; // (2)
void f(double) { std::cout << "Derived::Double!" << std::endl; } // (3)
};
int main(int, char **) {
Derived d;
d.f(21); //Base::Int!
d.f(1.1); //Derived::Double!
Base* p = &d;
p->f(21); //Base::Int!
p->f(0.1); //Derived::Double!
return 0;
}
using 相当于将父类的函数名 f 引入到了派生类。此时就可以正常重载了
604

被折叠的 条评论
为什么被折叠?



