在《C++ Primer中文版第4版》书的第499页有个习题15.23,现将其进行略微地修改,整理如下:
#include <iostream>
#include <string>
using namespace std;
struct Base {
int foo(int) { return 0; }
protected:
int bar;
double foo_bar;
};
struct Derived : public Base {
int foo(string) { return 0; };
/*
* 原书中,此函数的名字为bar,这是个语法错误:重定义。
* (因为同一个类中出现了两个名字相同的成员)
*/
bool bar_fun(const Base &pb) {
/*
* 编译不通过。
* 在Drived类中,无权访问基类Base类型的对象的protected成员。(P475, 15.2.2)
* 建议将函数改成:bool bar_fun(const Derived &pb)
*/
return foo_bar == pb.foo_bar;
}
void foobar() {
bar = 1; //本意是想给Base类中的int型bar赋值,应改为Base::bar = 1;
/*
* 下面这条语句为测试语句,若执行上述的bar=1语句,
* 编译不会出错,但输出的结果是一个笑脸;
* 若赋给bar大于127,则会出现“截断常数值”的警告。
* (不太理解,为什么这里整形值可以成功地赋值给string类型的变量,
* 若在main函数中写如下的代码则无法通过编译:
* string s = 1;)
*/
cout << bar << endl;
}
protected:
string bar; //注意:Base中的int型bar将被隐藏
};
int main() {
Derived d;
/*
* 编译不通过:参数类型不匹配。本意是想调用基类中的foobar成员函数,
* 应改为d.Base::foobar(1024);
*/
d.foo(1024);
d.foobar();
return 0;
}
引用此书第499页中的一句话来结束本文:设计派生类时,只要可能,最好避免与基类成员的名字冲突。
References:
《C++ Primer中文版第4版》P499