首页 > 试题广场 >

关于类成员函数的重载、覆盖和隐藏,下面说法错误的是()

[单选题]
关于类成员函数的重载、覆盖和隐藏,下面说法错误的是()
  • 重载函数必须要在同一个类中
  • 派生类函数覆盖基类函数,基类函数最好不要有virtual关键字
  • 如果派生类的函数与基类的函数名相同,通过派生类的实例也只能调用到派生类的函数。
  • 重载函数不必使用virtual关键字修饰

类成员函数的重载、覆盖和隐藏区别 (C++)

      这是本人第一次写博客,主要是想记录自己的学习过程、心得体会,一是可以方便以后回顾相关知识,二是可以与大家相互学习交流。

      关于C++中类成员函数的重载、覆盖和隐藏区别,第一次看到这个问题是在准备找工作的时候在牛客网中(http://www.nowcoder.com/questionTerminal/266d3a6d4f1b436aabf1eff3156fed95)看到的,后来也有遇到一些题在考察这个知识点,只要理解了他们的区别,还是可以正确的解答有关这个知识点的题。看到牛客网中有大牛的解释很好,故摘录保存。

1.成员函数被重载的特征:

(1)相同的范围(在同一个类中);

(2)函数名字相同

(3)参数不同

(4)virtual 关键字可有可无。

2.覆盖是指派生类函数覆盖基类函数,特征是:

(1)不同的范围(分别位于派生类与基类);

(2)函数名字相同

(3)参数相同

(4)基类函数必须有virtual 关键字

3.“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:

(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。

(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)。

 

 有关重载,应该是很好理解的(在同一个类中,函数名相同,函数的参数类型和个数不同),此处不予更多的说明,对于覆盖和隐藏(主要在基类和派生类中体现),借助下面这个例子来直观的说明:

#include<iostream>
using namespace std;

class People {
public:
// 隐藏:是指派生类的函数屏蔽基类函数
// 隐藏规则1:
// 1) 函数名相同 && 参数不同
// 2) virtual不影响
void getId_different_params() {cout << "People::getId_different_params" << endl;}
virtual void getName_different_params() {cout << "People::getName_different_params" << endl;}

// 隐藏规则2:
// 1) 函数名相同 && 参数相同
// 2) 无virtual
void getPhone_same_params() {cout << "People::getPhone_same_params" << endl;}

// 覆盖规则:
// 1) 函数名相同 && 参数相同
// 2) 有virtual
virtual void getAddress_same_params() {cout << "People::getAddress_same_params" << endl;}
};

class Children : public People {
public:
// 隐藏:是指派生类的函数屏蔽基类函数
// 隐藏规则1:
// 1) 函数名相同 && 参数不同
// 2) virtual不影响
void getId_different_params(int) {cout << "Children::getId_different_params(int)" << endl;}
virtual void getName_different_params(int) {cout << "Children::getName_different_params(int)" << endl;}

// 隐藏规则2:
// 1) 函数名相同 && 参数相同
// 2) 无virtual
void getPhone_same_params() {cout << "Children::getPhone_same_params" << endl;}

// 覆盖规则:
// 1) 函数名相同 && 参数相同
// 2) 有virtual
virtual void getAddress_same_params() {cout << "Children::getAddress_same_params" << endl;}
};

void main()
{

Children *c = new Children();
c->getId_different_params(1);
c->getName_different_params(1);
c->getPhone_same_params();
c->getAddress_same_params();
/*输出为:
Children::getId_different_params(int)
Children::getName_different_params(int)
Children::getPhone_same_params
Children::getAddress_same_params
*/


People *p = new Children();
p->getId_different_params();
p->getName_different_params();
p->getPhone_same_params();
p->getAddress_same_params();

/*输出为:
People::getId_different_params         //由于子类中的函数只是隐藏了基类中的函数而没有覆盖,因为指针为基类指针,故调用基类函数
People::getName_different_params    //由于子类中的函数只是隐藏了基类中的函数而没有覆盖,因为指针为基类指针,故调用基类函数
People::getPhone_same_params       //由于子类中的函数只是隐藏了基类中的函数而没有覆盖,因为指针为基类指针,故调用基类函数
Children::getAddress_same_params // 由于子类中的函数覆盖了基类中的函数,虽然指针为基类指针,但是会调用子类函数
*/
}

发表于 2020-08-06 08:28:29 回复(2)
感觉答案有问题:
子类对象.父类class::函数名称();就调用了子类函数了
发表于 2020-11-23 14:40:19 回复(2)

1.成员函数被重载的特征:

(1)相同的范围(在同一个类中);

(2)函数名字相同

(3)参数不同

(4)virtual 关键字可有可无。

2.覆盖是指派生类函数覆盖基类函数,特征是:

(1)不同的范围(分别位于派生类与基类);

(2)函数名字相同

(3)参数相同

(4)基类函数必须有virtual 关键字

3.“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:

(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。

(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)。

发表于 2023-07-03 11:52:02 回复(0)
我的理解,首先要理解这三个名词:(我按照 effective c++来思考的,结果和中文有偏差于是选错了。。。)
重载、覆盖和隐藏
重载(overload)是发生在同一个类里面,所以不需要用 virtual 修饰。
覆盖(override)指的是继承基类函数,这个过程需要 virtual
隐藏(overwrite)指的是重写了基类中的某些函数,于是名称遮掩了

这么看来 B 选项应该是基类必须要提供 virtual 关键字。
发表于 2023-03-02 11:23:03 回复(0)
覆盖是会发生在实现多态的情况下,而一隐藏是发生在继承的情况下。
如果派生类的函数与基类的函数名相同,通过派生类的实例也只能调用到派生类的函数。
这个选项还是有疑问?
class Base
{
public :
    Base()
    {
        m_A = 100;
    }

    void func()
    {
        cout << "Base - func()调用 " << endl;
    }

    void func(int a)
    {
        cout << "Base - func(int a)调用 " << endl;
    }

    int m_A;
};

class Son :public Base
{
public:

    Son()
    {
        m_A = 200;
    }

    void func()
    {
        cout << "Son - func()调用 " << endl;
    }
    int m_A;
};

//同名成员函数处理
void test02()
{
    Son s;
    s.Base::func();
    s.Base::func(100);      通过添加作用域还是可以访问到基类的函数

}

发表于 2020-09-06 18:03:16 回复(0)

A. 重载函数必须要在同一个类中。 这是正确的说法。重载函数是指在同一个类中定义的函数,它们具有相同的名称但参数列表不同,可以根据不同的参数类型或参数个数进行函数重载。

B. 派生类函数覆盖基类函数,基类函数最好不要有 virtual 关键字。 这是错误的说法。如果希望派生类能够覆盖基类的函数,基类函数应该使用virtual关键字进行声明。只有将基类函数声明为virtual,派生类才能使用相同的函数名和参数列表来覆盖基类函数,实现运行时的动态多态性。

C. 如果派生类的函数与基类的函数名相同,通过派生类的实例也只能调用到派生类的函数。 这是正确的说法。当派生类中定义了和基类同名的函数时,通过派生类的实例调用该函数时,会优先调用派生类中的函数。这被称为函数的隐藏,派生类函数将隐藏基类函数。(通过加作用域可以调用基类成员)

D. 重载函数不必使用virtual关键字修饰。 这是正确的说法。重载函数不需要使用virtual关键字进行修饰。重载是静态的,是根据函数的参数列表进行选择调用的,与虚函数的动态多态性没有直接关系。

编辑于 2023-11-14 15:36:43 回复(0)
重载(Overloading),覆盖(Overriding),和隐藏(Hiding)是面向对象编程中的三个重要概念,它们分别用于描述不同的特性。

1.重载(Overloading):


2.定义: 重载是指在同一个作用域内,使用相同的名称但是参数列表不同的多个函数或操作符。
3.示例:
 int add(int a, int b) {
     return a + b;
 }

 double add(double a, double b) {
     return a + b;
 }

4.特点: 重载函数或操作符可以有不同的参数类型、个数,但是返回类型通常不能作为重载的区分标准。


5.覆盖(Overriding):


6.定义: 覆盖是指派生类重新定义基类中已经存在的、具有相同签名(函数名和参数列表)的虚函数。
7.示例:
 class Base {
 public:
     virtual void print() const {
         cout &lt;&lt; "Base class\n";
     }
 };

 class Derived : public Base {
 public:
     void print() const override {
         cout &lt;&lt; "Derived class\n";
     }
 };

8.特点: 覆盖关系通常涉及到基类和派生类,使用关键字 override 明确表示覆盖。


9.隐藏(Hiding):


10.定义: 隐藏是指派生类中定义了与基类中的成员同名但具有不同参数列表的成员函数,导致基类的成员在派生类中被隐藏。
11.示例:
 class Base {
 public:
     void display() const {
         cout &lt;&lt; "Base class\n";
     }
 };

 class Derived : public Base {
 public:
     void display(int x) const {
         cout &lt;&lt; "Derived class with " &lt;&lt; x &lt;&lt; "\n";
     }
 };

12.特点: 隐藏不涉及虚函数,隐藏的成员在派生类中完全替代了基类的同名成员,而不考虑其参数列表。

区别总结:

13.重载:
14.发生在同一类中或者同一作用域中的不同函数。
15.参数列表不同。
16.与返回类型无关。
17.覆盖:
18.发生在继承关系中的基类和派生类之间。
19.函数签名(函数名和参数列表)相同,关键字 override 明确表示覆盖。
20.隐藏:
21.发生在继承关系中的基类和派生类之间。
22.函数名相同,但参数列表不同。
23.不涉及虚函数,派生类中的同名函数完全替代了基类的函数。

发表于 2023-12-18 20:34:34 回复(0)
C选项也有点问题,只能说是“不能通过变量名+'.'运算符直接调用到”。
通过很常见的其他方法也是可以访问到的。
发表于 2023-04-21 09:15:26 回复(0)
B选项应该为必须有virtual关键字
发表于 2022-07-21 09:13:09 回复(0)
D怎么是对的??
发表于 2021-04-02 11:56:48 回复(0)
D为什么对?
发表于 2021-03-02 22:39:14 回复(0)
D是对的?
编辑于 2020-12-04 16:24:56 回复(0)
重载函数不一定非要在一个类里面阿,普通全局函数也可以重载阿
发表于 2020-08-13 20:12:36 回复(2)