重载、覆盖和隐藏
部分文字内容摘自《高质量C++/C编程》
链接:http://man.chinaunix.net/develop/c&c++/c/c.htm#_Toc520634042
1 重载 Overload
1) 相同的范围,在同一个类中。
2) 函数名相同,参数不同。
3) virtual可有可无。
这在平时设计中用的比较多,比如游戏中角色说话,可以设计成:
void SendDialog(const char* content); // 默认
void SendDialog(const char* content, char color); // 内容颜色
void SendDialog(const char* content, char effect); // 带特效
...
2 覆盖(重写) Override
1) 不同的范围,分别位于基类和派生类。
2) 函数名相同,参数相同。
3) 基类中带有virtual关键字。
这在平时用的也很多,现在又添加了override关键字,等于派生类告诉基类,我
不使用你提供的方法,我要自己实现。
一个据说很俗,我也没看出哪里俗的例子:
计算面积:
class Shape
{
public:
virtual float Area(float x, float y) { return 0; }
// ...
}
class Rectangle : public Shape
{
public:
virtual float Area(float x, float y) { return x * y; }
}
class Triangle : public Shape
{
public:
virtual float Area(float x, float y) { return (x * y * 0.5); }
}
3 隐藏
1) 派生类中的函数与基类中的函数同名,参数不同,则基类同名函数被隐藏。
2) 派生类中的函数与基类中的函数名相同,参数也相同,基类中没有virtual关键字,基类同名函数被隐藏。
(如果有带virtual关键字,则为覆盖)
所谓隐藏,换个说法就是不能被调用了。
针对1)的例子:
class Rectangle
{
public:
void SetWith(double w) { m_width = w; }
void SetHeight(double h) { m_height = h; }
private:
double m_width;
double m_height;
};
class Square : public Rectangle
{
public:
void SetWith(double w, bool module)
{
Rectangle::SetWith(w);
Rectangle::SetHeight(w);
}
void SetHeight(double h)
{
Rectangle::SetWith(h);
Rectangle::SetHeight(h);
}
};
{
public:
void SetWith(double w) { m_width = w; }
void SetHeight(double h) { m_height = h; }
private:
double m_width;
double m_height;
};
class Square : public Rectangle
{
public:
void SetWith(double w, bool module)
{
Rectangle::SetWith(w);
Rectangle::SetHeight(w);
}
void SetHeight(double h)
{
Rectangle::SetWith(h);
Rectangle::SetHeight(h);
}
};
void func()
{
Square s;
// 编译都无法通过,因为派生类隐藏了基类的SetWith,
// 无法调用基类SetWith函数。
s.SetWith(32);
}
针对2):
换俗点的说法,派生类自己有一个和基类一模一样的,干嘛还要调用基类的。
对于隐藏,有一个要特别注意的地方。
class Rectangle
{
public:
void SetWith(double w) { m_width = w; }
void SetHeight(double h) { m_height = h; }
private:
double m_width;
double m_height;
};
class Square : public Rectangle
{
public:
void SetWith(double w)
{
Rectangle::SetWith(w);
Rectangle::SetHeight(w);
}
void SetHeight(double h)
{
Rectangle::SetWith(h);
Rectangle::SetHeight(h);
}
};
{
public:
void SetWith(double w) { m_width = w; }
void SetHeight(double h) { m_height = h; }
private:
double m_width;
double m_height;
};
class Square : public Rectangle
{
public:
void SetWith(double w)
{
Rectangle::SetWith(w);
Rectangle::SetHeight(w);
}
void SetHeight(double h)
{
Rectangle::SetWith(h);
Rectangle::SetHeight(h);
}
};
void func(Rectangle& r)
{
r.SetWith(32);
}
void main()
{
Square s;
// func中调用的是Rectangle::SetWith,
// 意味着正方形的高是一个任意值
func(s);
return 0;
}