首页 > 试题广场 >

关于重载和多态正确的是

[单选题]
关于重载和多态正确的是
  • 如果父类和子类都有相同的方法,参数个数不同,将子类对象赋给父类后,由于子类继承于父类,所以使用父类指针
    调用父类方法时,实际调用的是子类的方法
  • 选项全部都不正确
  • 重载和多态在C++面向对象编程中经常用到的方法,都只在实现子类的方法时才会使用
  • class A{
    	void test(float a){cout<<"1";}
    };
    class B:public A{
    	void test(int b){cout<<"2";}
    };
    A *a=new A;
    B *b=new B;
    a=b;
    a.test(1.1);
    结果是1
    
推荐
答案是B
         A调用的是父类的方法,C重载也包含函数重载,D中a.test(1.1)是错误的,应该为(*a).test(1.1);然后在class A里面加public就对了,是这样:
	class A{public: void test(float a){cout<<"1";}
};

编辑于 2015-12-02 17:47:40 回复(13)
看是否虚函数才是第一
发表于 2016-01-31 00:18:36 回复(0)

选项A 正确,题目已经基于假设在重载和多态下;所以定义虚函数,在多态下;A假设为多态其想法 正确。

发表于 2019-10-21 22:28:56 回复(0)
选项D确实不该选,做过之后再来看,选D确实太傻了。
首先,class默认访问权限为private,故所有函数都不能在外部被调用。
其实,即使把函数的访问权限声明为public,也还是不对。通过指针调用函数,应该使用a->test(1.1); 错的离谱。
选D确实不该。
正确答案为B。
编辑于 2015-12-14 10:53:14 回复(19)
D选项有2点错误
1.class默认的属性为private,不能用对象调用private
2.好多人认为在基类的test加上virtual就对了,其实 不然,虚函数要求返回值,参数名,参数个数,函数类型都相同,很显然基类和派生类的参数类型是不同的。对,这个例子根本不是覆盖!它是隐藏,隐藏分为2种: (1) 派生类的函数与基类的函数同名,但是参数列表有所差异。此时,不论有无virtual关键字,基类的函数在派生类中将被隐藏。(2) 派生类的函数与基类的函数同名,参数列表也相同,但是基类函数没有virtual关键字。
发表于 2016-02-28 17:51:53 回复(5)
A选项:由于函数名不同参数不同,这实际上 属于函数的重定义,即在子类对象会覆盖父类的方法,但是定义的是一个基类指针,所以调用的是基类的方法。
C选项:函数重载值得是函数的名称相同,返回值可以不同,参数不同,在同一个作用域中的函数。
D选项:类的成员函数默认是private,子类不能直接访问即类的私有函数。并且,定义的类为指针,调用方式也不对。不能使用.操作符。
发表于 2017-07-14 20:40:14 回复(0)
A:选项,这种情况发生在多态的情况下
D:有两个错误a.test(1.1)应该是a->test(1.1);
其次:在类中没有生命任何权限默认的私有的,外部对象无法访问, a=b;也就是基类指针指向了派生类,调用的是基类的test(1.1)这个方法
发表于 2015-12-03 00:02:20 回复(1)
1.class默认的属性为private,不能用对象调用private
2.好多人认为在基类的test加上virtual就对了,其实 不然,虚函数要求返回值,参数名,参数个数,函数类型都相同,很显然基类和派生类的参数类型是不同的。不是覆盖!它是隐藏,隐藏分为2种: (1) 派生类的函数与基类的函数同名,但是参数列表有所差异。此时,不论有无virtual关键字,基类的函数在派生类中将被隐藏。(2) 派生类的函数与基类的函数同名,参数列表也相同,但是基类函数没有virtual关键字。
编辑于 2016-03-20 10:27:18 回复(0)
test是私有成员函数,无法访问。
发表于 2016-03-08 10:47:52 回复(0)

D选项,首先两个test函数都是private的(class默认访问级别为private),无法通过a来访问

a是一个指针,应该使用a->test(1, 1);。如果改成下面那样,那答案就是对的:

class A{
public:
    void test(float a) {cout<<"1";}
};
class B : public A {
public:
    void test(int b) {cout<<"2";}
};

int main() {
    A* a = new A;
    B* b = new B;
    a = b;
    a->test(1.1);    // 输出1
    return 0;
}

不管a实际指向的对象是谁,因为test并不是virtaul函数,并不展现出多态性,在编译时期就能决定调用哪个test,因此输出1


就算加上了virtual,答案也还是1,因为B中test函数的形参为int,而A中的形参为float,这并不满足多态的要求,依然是在编译时期就能决定调用哪个test,并且在B中A的test函数被隐藏

<details><summary>重写/重载/隐藏的区别(点击展开)</summary>
    重写(覆盖):是指派生类中存在重新定义的函数。其函数名,参数列表,返回值类型,所有都必须同基类中被重写的函数一致。只有函数体不同(花括号内),派生类调用时会调用派生类的重写函数,不会调用被重写函数。重写的基类中被重写的函数必须有virtual修饰。
    隐藏:是指派生类的函数屏蔽了与其同名的基类函数,注意只要同名函数,不管参数列表是否相同,基类函数都会被隐藏。
    重载:是指同一可访问区内被声明的几个具有不同参数列表(参数的类型,个数,顺序不同)的同名函数,根据参数列表确定调用哪个函数,重载不关心函数返回类型  
</details>

除非改成这样,才会输出2:

class A{
public:
    virtual void test(float a) {cout<<"1";}
};
class B : public A {
public:
    void test(float b) {cout<<"2";}
};

int main() {
    A* a = new A;
    B* b = new B;
    a = b;
    a->test(1.1);    // 输出2
    return 0;
}

这时候a指向对象b,展现多态,调用了class B中的test,因此输出2

编辑于 2022-04-25 08:29:13 回复(0)
  1)不论基类函数是否为virtual,只要有派生类函数与其同名但不同参,该基类函数在派生类中将被隐藏。(别与重载混淆)   2)基类函数非virtual,有派生类函数与此基类函数同名同参,此时该基类函数在派生类中将被隐藏。(别与覆盖混淆)
发表于 2017-10-15 13:32:19 回复(0)
D选项,在没有声明public时默认为private
发表于 2017-03-14 17:02:25 回复(0)

选项 A 中的描述是错误的,如果父类和子类都有相同的方法但参数个数不同,在将子类对象赋给父类后,通过父类指针调用父类方法时,实际仍然调用的是父类的方法。这是因为在编译时,调用的是与指针类型相匹配的方法,而不是实际对象类型相匹配的方法。

选项 C 中的描述也是错误的,重载和多态在面向对象编程中都是常见的概念,并且不仅仅用于实现子类的方法。

选项 D 中的代码有误,应该改为a->test(1.1f);,同时由于 test 方法在父类中没有被声明为虚函数,所以无法实现动态多态性,输出结果为 1。

发表于 2023-10-20 20:34:56 回复(0)
重载 :参数不一样 重写:虚函数 调用子类 重定义 隐藏:非虚函数 ,子类有效
编辑于 2023-03-26 22:31:12 回复(0)
D选项中对象不能对private成员进行调用 只可以在类内访问
A选项中没有虚函数,所以父类指针调用父类方法时 使用的仍然是父类函数
C++中重载:同一作用域的同名函数:1、同一个作用域     2、参数个数 参数顺序 参数类型不同  3、和函数返回值没有关系 4、const也可以作为重载条件
重定义:1、有继承 2、子类重新定义父类的同名成员(非virtual函数)
重写:1、有继承 2、子类重写父类的virtual函数 3、函数返回值、函数名字、函数参数、必须和基类中的虚函数一致
发表于 2018-11-25 19:29:27 回复(0)
D其实意思是对的,只是public和.test被诟病而已,因为没有virtual,所以调用的是基类方法。C++在没有virtual关键字的时候是静态编译,a就是基类指针,在编译阶段就已经定下来了,因此是调用基类方法。加上virtual的话,就是动态编译了,就会调用子类方法。那个叫花蝶恋只不过是不懂装懂罢了。
发表于 2022-01-17 21:03:04 回复(1)
class Base
{
public:
    virtual void f(float x) {cout << "基类::f(float)函数" << x << endl;}
    virtual void f(int x, int y) {cout << "基类::f(int, int)函数" << x << "," << y << endl;}
    virtual void f1(float x) {cout << "基类::f1(float)函数" << x << endl;}
    void g(float x) {cout << "基类::g(float)函数" << x << endl;}
    void g(int x, int y) {cout << "基类::g(int, int)函数" << x << "," << y << endl;}
    void h(float x) {cout << "基类::h(float)函数" << x << endl;}
    static void my(float x) {cout << "基类::my(float)函数" << x << endl;}
};
class Derived : public Base
{
public:
    virtual void f(float x) {cout << "子类::f(float)函数" << x << endl;}
    virtual void f1(int x) {cout << "子类::f1(int)函数" << x << endl;}
    void g(int x) {cout << "子类::g(int)函数" << x << endl;}
    void h(float x) {cout << "子类::h(float)函数" << x << endl;}
    static void my(float x) {cout << "子类::my(float)函数" << x << endl;}
};
Derived oDerived;
Base *pBase = &oDerived;
Derived *pDerived = &oDerived;

pBase->f(3.14f);                     // 子类::f(float)函数3.14
pDerived->f(3.14f);                     // 子类::f(float)函数3.14

pBase->f(1, 2);                         //    基类::f(int, int)函数1,2
//pDerived->f(1, 2);                  // 父类的f(int x, int y)被f(float x)屏蔽了,调用不了,编译错误

pBase->f1(3.14f);                     // 基类::f1(float)函数3.14
pDerived->f1(3.14f);                 // 子类::f1(int)函数3

// hide
pBase->g(3.14f);                     // 基类::g(float)函数3.14
pDerived->g(3.14f);                     // 子类::g(int)函数3

pBase->g(1, 2);                         // 基类::g(int, int)函数1,2
//pDerived->g(1, 2);                   // 父类的g(int x, int y)被g(int x)屏蔽了,调用不了,编译错误

// hide
pBase->h(3.14f);                     // 基类::h(float)函数3.14
pDerived->h(3.14f);                     // 子类::h(float)函数3.14

pBase->my(3.14f);                     // 基类::my(float)函数3.14
pDerived->my(3.14f);                 // 子类::my(float)函数3.14

只有基类、子类的方法为虚方法,以及函数声明完全一致时,才可以实现多态调用。
发表于 2019-10-17 20:53:56 回复(0)
A选项“将子类对象赋给父类后”这句话啥意思?
发表于 2019-04-19 11:28:13 回复(0)
D选项 A类中的函数应该为共有才能调用 同时a是指针应该用->而不是.
发表于 2019-01-04 21:11:21 回复(0)
没人发现B选项本身会产生悖论吗?应该改成其他选项均错误
发表于 2018-07-06 12:19:26 回复(0)
D 中应该使用对象调用成员函数,而不是指针a.test(1.1);
发表于 2018-06-02 10:55:56 回复(1)