C++开发初级


829 浏览 5 years, 3 months

6.3 方法重载

版权声明: 转载请注明出处 http://www.codingsoho.com/

方法重载

您己经注意到了,在类中可以编写多个构造函数,所有这些构造函数的名称都相同。这些构造函数只是参数数量或者类型不同。在C++中,可以对任何方法或函数做同样的事情。具体地讲,您可以重载函数或者方法,具体做法是将函数或者方法的名称用于多个函数,但是参数的类型或者数目不同。例如在SpreadsheetCell类中,可将setString()以及setValue()全部重命名为set()。类定义如下所示:

class SpreadsheetCell
{
 public:
  void set(double inValue);
  void set(const string& inString);
};

代码取自 SpreadsheetCellMethods\SpreadsheetCell.h

set()方法的实现保持不变。注意前面调用setValue()的两个构造函数现在必须调用set()。当编写调用set()的代码时,编译器根据传递的参数判断调用那个实例:如果传递了一个字符串,编译器调用字符串实例,如果传递了双精度值,编译器调用double实例。这就是所谓的重载解析(overload resolution)

您或许想对getValue()以及getString()做同样的事:将它们重命名为get()。然而,这样的代码将无法编译。C++不允许仅根据方法的返回类型重载方法名称,因为在许多情况下,编译器不可能判断调用那个方法实例。例如,如果任何地方都没有使用方法的返回值,编译器将无法判断您想要使用哪个方法实例。

还要注意,可以根据const重载方法。也就是说可以编写两个名称相同,参数也相同的方法,其中一个是const,另一个不是。如果是const对象是,就调用const方法,如果是非const对象,就调用非const方法。

在C++11中,重载方法可以被显式地删除,可以用这种方法禁止调用具有特定参数的成员函数。 例如,考虑下面的类:

class MyClass
{
public:
    void foo(int i);
};

可以用下面的方式调用foo()方法:

MyClass c;
c.foo(123);
c.foo(1.23);

在第二行,编译器将double值(1.23)转换为整型值(1),然后调用foo(int i)。编译器可能会给出警告,但是仍然会执行这一隐式转换。可以显式删除foo()的double实例,从而禁止编译器执行这一转换:

class MyClass
{
public:
    void foo(int i);
    void foo(double d) = delete;
};

通过这一改动,用double做参数调用foo()时编译器会给出错误提示而不是将其转换为整数。