C ++ - 方法和重载中的const关键字

时间:2017-01-18 10:15:00

标签: c++ overloading

为什么这个程序:

#include <iostream>
using namespace std;
class Base {
public:
  Base() { cout << "Costruttore Base" << endl; }
  virtual void foo(int) { cout << "Base::foo(int)" << endl; }
  virtual void bar(int) { cout << "Base::bar(int)" << endl; }
  virtual void bar(double) { cout << "Base::bar(double)" << endl; }
  virtual ~Base() { cout << "Distruttore Base" << endl; }
};
class Derived : public Base {
public:
  Derived() { cout << "Costruttore Derived" << endl; }
  void foo(int) { cout << "Derived::foo(int)" << endl; }
  void bar(int) const { cout << "Derived::bar(int)" << endl; }
  void bar(double) const { cout << "Derived::bar(double) const" << endl; }
  ~Derived() { cout << "Distruttore Derived" << endl; }
};
int main() {
  Derived derived;
  Base base;
  Base& base_ref = base;
  Base* base_ptr = &derived;
  Derived* derived_ptr = &derived;
  cout << "=== 1 ===" << endl;
  base_ptr->foo(12.0);
  base_ref.foo(7);
  base_ptr->bar(1.0);
  derived_ptr->bar(1.0);
  derived.bar(2);
  return 0;
}

在通话base_ptr->bar(1.0);中称为Base::bar(double),而derived_ptr->bar(1.0);则称为Derived::bar(double) const

我理解这是关于const关键字,但我不明白为什么编译器会选择不同的重载函数。

如果我删除const关键字,一切都按预期工作,在两种情况下调用Derived::bar

3 个答案:

答案 0 :(得分:3)

因为const更改了该功能的签名,所以它们会有所不同。要么同时创建基类和派生类const,否则一个人不会覆盖另一个。

答案 1 :(得分:2)

这是因为你并没有真正覆盖功能栏()。您正在使用不同的签名在派生类中定义 new 函数bar()。

因此要么删除派生类中的const,要么将const添加到上层类中bar()的签名中。 (或保持原样,但要知道你现在在派生类中有两个名为bar()的函数,其中一个是隐藏的)

答案 2 :(得分:2)

C ++ 11添加了override specifier以防止出现这类惊喜。使用bar(int)关键字和编译器只会编译代码,如果它确实覆盖。

假设覆盖<{em} bar(double)(这也适用于class Base { public: .... virtual void bar(int) { cout << "Base::bar(int)" << endl; } }; class Derived : public Base { public: ... //This isn't an override, program is well formed void bar(int) const { cout << "Derived::bar(int)" << endl; } };

bar

Derived中的const成员函数没有覆盖基类'自己。由于override资格不同,因此成员函数签名不同。 您在派生类中所做的只是添加一个新的重载并隐藏基类“的重载。

在派生类中添加class Base { public: .... virtual void bar(int) { cout << "Base::bar(int)" << endl; } }; class Derived : public Base { public: ... //This isn't an override, program is ill-formed, diagnostic required void bar(int) const override { cout << "Derived::bar(int)" << endl; } }; 关键字,如果编译器没有覆盖,编译器将给出诊断。

class Base {
public:
  ....
  virtual void bar(int) { cout << "Base::bar(int)" << endl; }
};

class Derived : public Base {
public:
  ...
  //This overrides
  void bar(int) override { cout << "Derived::bar(int)" << endl; }
};

要覆盖,成员函数签名必须相同。

# locally customisable values go in here
DATE_FORMAT = "%d/%m/%Y"
TIME_FORMAT = "%H:%M"
# etc.
# note this is Python code, so it's possible to derive default values by 
# interrogating the external system, rather than just assigning names to constants.

# you can also define short helper functions in here, though some would
# insist that they should go in a separate my_utilities.py module.

# from moinuddin's answer

def datetime_to_str(datetime_obj):
    return datetime_obj.strftime(DATE_FORMAT)

因此,无论何时想要覆盖,都要学会使用override关键字,这样可以省去一些麻烦。