首页 > 试题广场 >

下面说法错误的是()

[不定项选择题]
下面说法错误的是()
  • 在组合时,为了保证成员对象被正确清除,在组合类的析构函数中需要显式调用其成员对象的析构函数
  • 在类的继承层次中,可以自动进行向上和向下类型转换.而且都是安全的
  • 构造函数可以重载,析构函数不能重载
  • C++的派生类如果要覆盖一个继承到的成员函数,在基类中需要将该函数声明为virtual
推荐
没有仔细思考,做错了,不过我是这样想的:
A选项:在组合类的析构函数中并不需要显式调用其成员对象的析构函数,因为当执行组合类的析构函数时,其数据成员也会被销毁,对于类成员对象来说,成员对象销毁时,程序会自动调用其析构函数;不过对于组合类中new的指向类成员的指针,组合类需要自己去delete该指针;
B选项:显然是错的,在类继承层次中,基类在上,派生类在下,所以可以自动进行向上类型转换,即可以使基类指针和引用指向派生类对象,而不可以使派生类指针和引用指向基类对象;
C选项:对的,构造函数可以根据参数的不同实现函数重载,而因为析构函数没有参数,对于一个类来说也是唯一的,所以是不能重载的;
D选项:即派生类想要重写继承来的成员函数,需要用到virtual函数,来实现动态多态。
编辑于 2016-05-11 22:29:00 回复(9)
更多回答
对于D选项,为什么是错的?因为如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字,此时,基类的函数被隐藏,注意,是隐藏而不是覆盖。覆盖的基本特征之一就是 基类函数必须有virtual关键字。
发表于 2016-03-24 19:53:16 回复(3)
我觉得答案AB。推荐看《Effective C++》就比较简单了。
A:成员类对象在离开作用域的时候会调用其自身的析构函数,并不需要我们手动delete,就将其看做一个基本的局部对象即可。除非在构造的时候用了动态类存分配,这又是另外一回事了。
B:明显错误,参考《Effective C++》第39条,不要向下转型。
C:正确,比较简单
D:正确,也是《Effective C++》第37条,如果子类要重写父类方法,需要将父类该方法声明为virtual,实现RTTI。当然你可以不这样干,结果就是静态绑定。补充一点,重写就叫覆盖。如果没有virtual就是隐藏。
编辑于 2016-05-16 10:49:38 回复(3)
重载,覆盖和隐藏总结:
1.重载:函数名相同,参数列表不同,重载只是在类的内部实现,但是不能靠返回值来判断。
    特点:(1)相同的范围;(2)函数名字相同;(3)参数不同;(4)virtual可有可无。
2.覆盖:子类重新定义父类中相同名称和参数的虚函数,函数特征相同,但是具体实现不同,主要是在继承关系中出现。
    特点:(1)不同的范围,分别位于父类和子类中;(2)函数的名称相同;(3)参数相同;(4)基类必须有virtual。
3.隐藏:也叫重定义,是指子类屏蔽了父类与其同名的函数。
    特点:(1)如果子类的函数和父类的函数同名,但是参数不同,此时,不管有无virtual,父类的函数被隐藏。
              (2)如果子类的函数和基类的函数同名,参数也相同,若基类无virtual,则父类函数被隐藏,
发表于 2017-01-15 11:22:13 回复(0)

A项,不用显式调用。

B项,向上的类型转换(基类的指针和引用指向派生类)是安全的(派生类多的数据成员扔掉就行),向下的类型转换是不安全的(基类没有派生类的那些数据成员补不出来)。

另外类型转换后,调用虚函数即调用转换前的(真实类的)函数版本,调用普通函数即调用转换后的函数版本。

D项,重写虚函数是覆盖,重写普通函数是隐藏。覆盖中文意思即最后只留一个;隐藏即暗示最后两个都在。覆盖可理解为使用时只需一个指向虚函数表的指针,查虚函数表根据其类型调用其对应的那个版本。


编辑于 2018-10-19 22:32:40 回复(0)
D选项的关键词的覆盖,只有重写基类虚函数才是覆盖,重写普通函数叫重写隐藏。
发表于 2016-06-07 22:18:49 回复(0)
编辑于 2024-02-02 21:47:33 回复(0)
我以为覆盖是指 redefine, 没想到是 override 
发表于 2022-10-12 11:29:51 回复(0)
我觉得答案AB。推荐看《Effective C++》就比较简单了。
A:成员类对象在离开作用域的时候会调用其自身的析构函数,并不需要我们手动delete,就将其看做一个基本的局部对象即可。除非在构造的时候用了动态类存分配,这又是另外一回事了。
B:明显错误,参考《Effective C++》第39条,不要向下转型。
C:正确,比较简单
D:正确,也是《Effective C++》第37条,如果子类要重写父类方法,需要将父类该方法声明为virtual,实现RTTI。当然你可以不这样干,结果就是静态绑定。补充一点,重写就叫覆盖。如果没有virtual就是隐藏。
发表于 2022-05-15 15:36:03 回复(0)
<p>覆盖:虚函数,函数名,参数表,返回值类型均一致</p><p>隐藏:1非虚函数,函数同名即可</p><p>2虚函数,函数同名并且参数表不同</p>
发表于 2020-09-28 13:39:55 回复(0)
D选项,如果只是覆盖的话,不是必须声明虚函数吧
发表于 2020-07-04 18:32:06 回复(0)
覆盖和隐藏不同。
隐藏:是派生类中的函数和基类中函数同名,用派生类对象调用默认调用派生类中的。
覆盖:是把基类中的函数定义为虚函数,然后实现多态。
发表于 2019-08-01 10:11:31 回复(0)
总是看出题目:下面选项正确的是。。。。。。
不过还是选错了A
发表于 2019-04-01 14:27:04 回复(0)
含有成员对象的类为组合类
发表于 2018-03-14 21:19:43 回复(0)
借用RuAL. 重载,覆盖和隐藏总结: 1.重载:函数名相同,参数列表不同,重载只是在类的内部实现,但是不能靠返回值来判断。     特点:(1)相同的范围;(2)函数名字相同;(3)参数不同;(4)virtual可有可无。 2.覆盖:子类重新定义父类中相同名称和参数的虚函数,函数特征相同,但是具体实现不同,主要是在继承关系中出现。     特点:(1)不同的范围,分别位于父类和子类中;(2)函数的名称相同;(3)参数相同;(4)基类必须有virtual。 3.隐藏:也叫重定义,是指子类屏蔽了父类与其同名的函数。     特点:(1)如果子类的函数和父类的函数同名,但是参数不同,此时,不管有无virtual,父类的函数被隐藏。               (2)如果子类的函数和基类的函数同名,参数也相同,若基类无virtual,则父类函数被隐藏,
发表于 2017-10-09 16:56:02 回复(0)
错在D上了,覆盖即重写,基类的函数需要virtual修饰,才能在派生类中进而重写。
发表于 2017-07-07 13:28:16 回复(0)
D明明说的是 覆盖, 而不是隐藏。覆盖就是对的吧

发表于 2017-05-26 12:40:42 回复(0)
class B
{
    void DoSomething();
    virtual void vfun();
}
class C : public B
{
    void DoSomething();//首先说明一下,这个子类重新定义了父类的no-virtual函数,这是一个不好的设计,会导致名称遮掩;这里只是为了说明动态绑定和静态绑定才这样使用。
    virtual void vfun();
}
class D : public B
{
    void DoSomething();
    virtual void vfun();
}
D* pD = new D();
B* pB = pD;
针对D选项。
让我们看一下,pD->DoSomething()和pB->DoSomething()调用的是同一个函数吗?
不是的,虽然pD和pB都指向同一个对象。因为函数DoSomething是一个no-virtual函数,它是静态绑定的,也就是编译器会在编译期根据对象的静态类型来选择函数。pD的静态类型是D*,那么编译器在处理pD->DoSomething()的时候会将它指向D::DoSomething()。同理,pB的静态类型是B*,那pB->DoSomething()调用的就是B::DoSomething()。
让我们再来看一下,pD->vfun()和pB->vfun()调用的是同一个函数吗?
是的。因为vfun是一个虚函数,它动态绑定的,也就是说它绑定的是对象的动态类型,pB和pD虽然静态类型不同,但是他们同时指向一个对象,他们的动态类型是相同的,都是D*,所以,他们的调用的是同一个函数:D::vfun()。
参考链接:http://www.jb51.net/article/37245.htm
发表于 2017-03-01 11:10:39 回复(0)
没virtual就是隐藏了,有的话,是覆盖,也就是动态联编
发表于 2016-05-28 23:16:24 回复(0)
重载和virtual多态不是一个概念啊,另外D的话,copy牛友的原话,覆盖只是针对虚函数而言,对非虚函数就是隐藏了
编辑于 2016-04-27 12:23:08 回复(0)
D只是说要覆盖一个基类成员函数,那么重载不就可以了吗?求解答
发表于 2016-03-11 10:04:11 回复(1)