首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >方法和重载中的C++ - const关键字

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

Stack Overflow用户
提问于 2017-01-18 10:15:00
回答 3查看 358关注 0票数 4

出于这个原因,这个计划:

代码语言:javascript
复制
#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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-01-18 10:23:13

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

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

票数 2
EN

Stack Overflow用户

发布于 2017-01-18 10:21:54

这是因为const更改了函数的签名,所以它们是不同的。要么使基类和派生类同时生成const,要么使其中一个不覆盖另一个。

票数 3
EN

Stack Overflow用户

发布于 2017-01-18 10:26:16

C++11添加了 specifier,以防止这种意外。使用,override关键字,编译器将只编译您的代码,如果它确实覆盖。

接受bar(int)的假定覆盖(这也适用于bar(double) )

代码语言:javascript
复制
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关键字,编译器将给出一个诊断,如果它不覆盖。

代码语言:javascript
复制
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; }
};

若要重写,成员函数签名必须相同。

代码语言:javascript
复制
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; }
};

因此,当您想要重写时,请学习使用覆盖关键字,它将为您省去一些麻烦。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41716636

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档