学习面向对象的语言,了解继承是必不可少的。您可能觉得这太基础了,大家可都是老“996”了,还用介绍封装、继承、多态那老三样吗?
哎,您别着急。本文讲的是一个C++语言的小Trick,您或许了解也或许不了解,各位看官请细听分说。
按常理来说,如果父类的成员函数是public的,那么子类应该也能直接调用父类定义的函数,所谓的“继承”也便是这个含义。口说无凭,手上见真章,说有这么两个类,它这样,这样,这样……
啪啪啪,你甩给我一段代码:
#include <iostream>
#include <string>
using namespace std;
class Staff {
public:
void set_birth(string birth) {
_birth = birth;
}
private:
string _birth;
};
class Leader:public Staff {
};
int main() {
Leader s;
s.set_birth("1990/10/10");
return 0;
}
这段代码没问题,编译也能过。父类有个成员函数set_birth,接收一个string类型,设置生日。比如"1990/10/10"。子类可以直接调用set_birth。
“这有什么值得一说的?”你夺门而出,我连忙追上去让你把门还我。
您接着瞧,如果子类现在需要实现一个传入int类型的set_birth呢?
class Leader:public Staff {
public:
void set_birth(int birth) {
set_birth(to_string(birth));
}
};
int main() {
Leader s;
s.set_birth(19901010);
return 0;
}
子类set_birth(int)内调用了父类的set_birth(string)。看着没问题,但是编译却报错了:
demo.cpp:17:19: error: no viable conversion from 'std::__1::string' (aka 'basic_string<char, char_traits<char>, allocator<char> >') to 'int'
set_birth(to_string(birth));
^~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/string:875:5: note: candidate function
operator __self_view() const _NOEXCEPT { return __self_view(data(), size()); }
^
demo.cpp:16:24: note: passing argument to parameter 'birth' here
void set_birth(int birth) {
^
1 error generated.
编译器编译子类时似乎不能识别set_birth(string)。我们再测试一下是不是真的不能识别:
class Leader:public Staff {
public:
void set_birth(int birth) {
}
};
int main() {
Leader s;
s.set_birth("19901010");
return 0;
}
这样编译,也报错:
demo.cpp:22:17: error: cannot initialize a parameter of type 'int' with an lvalue of type 'const char [9]'
s.set_birth("19901010");
^~~~~~~~~~
demo.cpp:16:24: note: passing argument to parameter 'birth' here
void set_birth(int birth) {
^
1 error generated.
果然,子类已经无法调用父类的public成员函数了。明明刚才还可以,怎么set_birth(string)对子类突然不可见了呢?
奥秘在于,子类重载了父类的同名函数。此时父类的函数确实对子类是不可见的……
这其实不是一个复杂的知识点,只是容易让人稍不留意就遗忘。
解决方案是什么呢?其实也不难,想办法让父类的同名函数对子类可见!
class Leader:public Staff {
public:
using Staff::set_birth;
void set_birth(int birth) {
set_birth(to_string(birth));
}
};
int main() {
Leader s;
s.set_birth(19901010);
return 0;
}
一行using就可以搞定!
using Staff::set_birth;
注意这不是C++11!这是C++11之前就有的using语法。
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8