重载、覆盖和隐藏
2014-04-02 11:15
211 查看
部分文字内容摘自《高质量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);
}
};
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);
}
};
void func(Rectangle& r)
{
r.SetWith(32);
}
void main()
{
Square s;
// func中调用的是Rectangle::SetWith,
// 意味着正方形的高是一个任意值
func(s);
return 0;
}
链接: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);
}
};
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);
}
};
void func(Rectangle& r)
{
r.SetWith(32);
}
void main()
{
Square s;
// func中调用的是Rectangle::SetWith,
// 意味着正方形的高是一个任意值
func(s);
return 0;
}
相关文章推荐
- overload和override的区别
- 解析abstract与override究竟可不可以同时使用
- Javascript 面向对象 重载
- php面向对象全攻略 (八)重载新的方法
- Java方法的覆盖与隐藏的区别分析
- JavaScript 通过模式匹配实现重载
- 第十一节 重载 [11]
- ASP.NET方法如何重载需要必备哪些条件
- Javascript 面向对象之重载
- PHP和JAVA中的重载(overload)和覆盖(override) 介绍
- C++中overload,override,overwrite的区别详细解析
- C++重载运算符的规则详解
- C# new和override的区别分析
- 有关于JS构造函数的重载和工厂方法
- 类成员函数的重载、覆盖与隐藏之间的区别总结
- C++概念重载、覆盖、隐藏的使用说明
- 重载&方法返回值
- 方法的重载及参数传递
- 子类重定义父类方法调用父类方法
- Remove '@override' annotation解决办法