Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 重载与重写_C++_Overriding_Overloading - Fatal编程技术网

C++ 重载与重写

C++ 重载与重写,c++,overriding,overloading,C++,Overriding,Overloading,我对这两个术语有点困惑,希望澄清一些疑问 据我所知,函数重载意味着在同一个类中有多个具有相同名称的方法,但要么具有不同数量的参数,要么具有不同类型的参数,要么具有不同的参数序列,而不考虑返回类型,这对函数名称的损坏没有影响 上述定义是否也包括“…在同一类中或跨相关类(通过继承相关)…” 函数重写与虚函数、相同的方法签名(在基类中声明为virtual)相关,并被重写以在子类中实现 我想知道一个场景,下面是代码: #include <iostream> class A { pu

我对这两个术语有点困惑,希望澄清一些疑问

据我所知,
函数重载
意味着在同一个类中有多个具有相同名称的方法,但要么具有不同数量的参数,要么具有不同类型的参数,要么具有不同的参数序列,而不考虑返回类型,这对函数名称的损坏没有影响

上述定义是否也包括“…在同一类中或跨相关类(通过继承相关)…”

函数重写与虚函数、相同的方法签名(在基类中声明为virtual)相关,并被重写以在子类中实现

我想知道一个场景,下面是代码:

#include <iostream>

class A
{
    public:
    void doSomething(int i, int j)
    {
        cout<<"\nInside A::doSomething\n";
    }
};

class B: public A
{
    public:
    void doSomething(int i, int j)
    {
        cout<<"\nInside B::doSomething\n";

    }
};

int main()
{
    B obj;
    obj.doSomething(1,2);
    return 0;

} 
#包括
甲级
{
公众:
无效剂量测定(int i,int j)
{

cout在这种情况下两者都不是。派生类方法是基类方法。

重载是定义具有相同名称但不同签名的多个方法的过程;重写是指子类中的函数与父类中的虚拟函数具有相同的签名

class Test {
  // Test::func is overloaded
  virtual void func(int x);
  virtual void func(double y);
};

class Child : public Test {
  // Child::func overrides Test::func
  virtual void func(int x); 
};
  • 隐藏是指由于嵌套范围或派生类(3.3.7/1)中的声明而无法访问范围中的定义
名称可以通过嵌套声明性区域或派生类中相同名称的显式声明隐藏

  • 重写是指在派生类中替换虚拟成员(请参见10.3/2)
如果在类基类中声明了虚拟成员函数vf,并且在派生类、直接或间接从基类派生的类中声明了与Base::vf具有相同名称和相同参数列表的成员函数vf,则派生::vf也是虚拟的,并且它重写了Base::vf

  • 重载是指在同一范围内为同一名称同时存在多个声明(13/1)
当为同一作用域中的单个名称指定两个或多个不同的声明时,该名称被称为重载

  • 此外,还可以通过自己的实现替换标准库中的操作员new和delete(18.4.1.1/2、18.4.1.1/6、18.4.1.1/11、18.4.1.2)
因此,这显然是一个隐藏的情况。

函数重载是指当您有多个函数在其参数列表中不同时,或者如果它们是成员函数,则在其
常量中不同。(在其他一些语言中,您也可以基于返回类型重载,但C++不允许。)
示例:

void f(int);
void f(char);

class some_class {
  void g();
  void g() const;
};
class base {
  void f();
  virtual void g();
};

class derived : public base {
  void f();
  void g();
};
class base {
  void f(int);
  void f(char);
};

class derived1 : public base {
  void f(double);
};

void f()
{
  derived1 d;
  d.f(42); // calls derived1::f(double)!
}

class derived2 : public base {
  using base::f; // bring base class versions into derived2's scope
  void f(double);
};

void g()
{
  derived2 d;
  d.f(42); // calls base::f(int)!
}

函数重写是当您重新定义具有相同签名的基类函数时。通常,这仅在基类函数为虚拟函数时才有意义,否则将调用函数(基类或派生类的版本)在编译时使用引用/指针的静态类型确定。
示例:

void f(int);
void f(char);

class some_class {
  void g();
  void g() const;
};
class base {
  void f();
  virtual void g();
};

class derived : public base {
  void f();
  void g();
};
class base {
  void f(int);
  void f(char);
};

class derived1 : public base {
  void f(double);
};

void f()
{
  derived1 d;
  d.f(42); // calls derived1::f(double)!
}

class derived2 : public base {
  using base::f; // bring base class versions into derived2's scope
  void f(double);
};

void g()
{
  derived2 d;
  d.f(42); // calls base::f(int)!
}

函数隐藏是指在派生类(或内部作用域)中定义的函数与在基类(或外部作用域)中声明的同名函数具有不同的参数列表。在这种情况下,派生类的函数隐藏基类函数。您可以通过使用
声明将基类函数显式引入派生类的作用域来避免这种情况。
示例:

void f(int);
void f(char);

class some_class {
  void g();
  void g() const;
};
class base {
  void f();
  virtual void g();
};

class derived : public base {
  void f();
  void g();
};
class base {
  void f(int);
  void f(char);
};

class derived1 : public base {
  void f(double);
};

void f()
{
  derived1 d;
  d.f(42); // calls derived1::f(double)!
}

class derived2 : public base {
  using base::f; // bring base class versions into derived2's scope
  void f(double);
};

void g()
{
  derived2 d;
  d.f(42); // calls base::f(int)!
}


以防万一:基于这些定义,我将这里讨论的场景称为覆盖。

Your func(int x)是隐藏,而不是重写,需要虚拟关键字。坦率地说,正如您所解释的,我确实理解重载和重写之间的区别。我只是对我引用的特定示例感到困惑。正如我现在所理解的,它既不是刚派生的类,也不是隐藏基类方法的派生类,因为在派生和重写之间没有重载解析基类和覆盖类特别需要虚拟关键字。这也演示了另一个<代码>特性< /C> >;(-C++)。
即使传递了一个double,您实际上也调用了int版本。这是因为名称解析将在子级中停止,因为方法名称匹配,因此您不会得到基的重载选择(除非使用子句将这些声明从父级显式带到子级中)。这是一个隐藏、重载和重写的过程!
Child::func(int)
重写重载的
Test::func(int)
并隐藏重载的
Test::func(double)
。调用
Child.Test(3.141592653589793)
您将调用
Child::Test(int)
,pi转换为int。有时隐藏函数称为重载-实际上,您重载的是this的静态类型以及“other”的类型参数。但是,除非替换基类中的所有重载,否则您将进行减法运算和加法运算,因此这与重载自由函数并不完全相同。可能使用“重载”因此是不正确的,但我确实遇到过并亲自使用过它。@Steve和@Space:这不是重写吗?这肯定不是函数隐藏,因为如果是,那么您可以在派生类中取消隐藏它,然后这两个函数都将可用。但事实并非如此。它重写了!@Steve,@Nawaz,@Space:实际上,这是调用的重载。“重载”严格地说是当您有几个具有不同参数列表的函数(或具有不同cv限定的成员函数)时@sbi:我看到你编辑了格式化的@AProgrammers答案,上面说这是
隐藏
的情况,你上面的评论说它的
覆盖了
,它相互矛盾……@Als:我没有判断@AProgrammer的答案,我只是更正了