141.牛客网C++刷题8
作者:互联网
1.字符常量可以参与任何整数运算,char型也可以假想为int,我们在用switch语句时,括号里面只能是int和char
2.函数的形式参数(形参)属于局部变量
3.有如下代码:
struct A1{
virtual ~A1(){}
};
struct A2{
virtual ~A2(){}
};
struct B1 : A1, A2{};
int main()
{
B1 d;
A1* pb1 = &d;
A2* pb2 = dynamic_cast<A2*>(pb1); //L1
A2* pb22 = static_cast<A2*>(pb1); //L2
return 0;
}
A.L1语句编译失败,L2语句编译通过
B.L1语句编译通过,L2语句编译失败
C.L1,L2都编译失败
D.L1,L2都编译通过
答案:B
解析:dynamic_cast是运行时检查,虽然pb1是A1类型的,但是指向的实体却是子类,所以子类转父类A2完全是可以的。
但是static_cast比较“死脑筋”,在编译期检查,这样是不检查指针指向的值的,于是发现pb1是A1类型,A1想转A2?报错
4.static数据成员在类内声明,在类外定义和初始化,在类的外部不能再次指定static(特例:当整型const static数据成员被常量表达式初始化时,就可以在类的内部声明时进行初始化)
静态数据成员属于类的所有实例(即对象),所有对象共享一份,在类被实例化时创建,通过类和对象都可以进行访问
static成员实质上是加了“访问控制”的全局变量/函数,所以当然受访问控制符的控制
5.动态联编是以虚函数为基础的
动态联编调用虚函数操作是指向对象的指针或引用
动态联编是在运行时确定所调用的函数代码的
通常来说联编就是将模块或者函数合并在一起生成可执行代码的处理过程,同时对每个模块或者函数调用分配内存地址,并且对外部访问也分配正确的内存地址,它是计算机程序彼此关联的过程。按照联编所进行的阶段不同,可分为两种不同的联编方法:静态联编和动态联编
静态联编是指在编译阶段就将函数实现和函数调用关联起来,因此静态联编也叫早绑定,在编译阶段就必须了解所有的函数或模块执行所需要检测的信息,它对函数的选择是基于指向对象的指针(或者引用)的类型,C语言中,所有的联编都是静态联编,并且任何一种编译器都支持静态联编。
动态联编是指在程序执行的时候才将函数实现和函数调用关联,因此也叫运行时绑定或者晚绑定,动态联编对函数的选择不是基于指针或者引用,而是基于对象类型,不同的对象类型将做出不同的编译结果。C++中一般情况下联编也是静态联编,但是一旦涉及到多态和虚拟函数就必须要使用动态联编了。下面将介绍一下多态
多态:字面的含义是具有多种形式或形态。C++多态有两种形式,动态多态和静态多态;动态多态是指一般的多态,是通过类继承和虚函数机制实现的多态;静态多态是通过模板来实现,因为这种多态实在编译时而非运行时,所以称为静态多态
6.纯虚函数是一种特殊的虚函数,它没有具体的实现
抽象类是指具有纯虚函数的类
抽象类只能作为基类来使用,其纯虚函数的实现由派生类给出
7.确定如下语句运行时输出什么?
class base
{
public:
virtual void func(){cout << "base" << endl;}
};
class derived : public base
{
public:
void func(){cout << "derived" << endl;}
}
derived dr ;
base *pbs =&dr;
pbs->func();
答案:derived
解析:
当函数为虚函数时,子类继承基类会完全覆盖基类虚函数,强制指针类型转换无法改变类内虚函数的函数体
虚函数调用与指针类型无关,基类调用基类虚函数,子类调用子类虚函数
若为普通函数,普通函数同名但未被覆盖,优先匹配与指针类型匹配的同名函数
8.假定一个类的构造函数为A(int aa, int bb) {a = aa–; b = a*bb;},则执行A x(4,5);语句后,x.a和x.b的值分别为多少?
答案:4和20
解析:aa = 4, bb = 5, a = aa–之后,a的值为4,aa的值为3,b = a * bb = 4 * 5 = 20
9.sizeof(“hello”);的结果为6,会加上’\0’
strlen(“world”);的结果为5,不会加上’\0’
10.通过基类对象名、指针只能使用从基类继承的成员
11.如果想使一个数组中全部元素的值为0,可以写成int a[10]={0*10};。请问这句话的说法是正确的吗?
答案:正确
12.类成员的访问权限有:
公有:public
私有:private
保护:protected
13.关于C++中的友元函数说法正确的是?
A.友元函数需要通过对象或指针调用
B.友元函数是不能被继承的
C.友元函数没有this指针
D.友元函数破环了继承性机制
答案:BC
解析:有些情况下,允许特定的非成员函数访问一个类的私有成员,同时仍阻止一般的访问,这是很方便做到的。例如被重载的操作符,如输入或输出操作符,经常需要访问类的私有数据成员。友元(frend)机制允许一个类将对其非公有成员的访问权授予指定的函数或者类,友元的声明以friend开始,它只能出现在类定义的内部,友元声明可以出现在类中的任何地方:友元不是授予友元关系的那个类的成员,所以它们不受其声明出现部分的访问控制影响。通常,将友元声明成组地放在类定义的开始或结尾是个好主意。
1)友元函数
友元函数是指某些虽然不是类成员函数却能够访问类的所有成员的函数。类授予它的友元特别的访问权,这样该友元函数就能访问到类中的所有成员。
2)友元类
友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员),即通过类的对象访问类的所有成员。当希望一个类可以存取另一个类的私有成员时,可以将该类声明为另一类的友元类
关于友元类的注意事项:
(1)友元关系不能被继承
(2)友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明
(3)友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的申明
3)友元成员函数
使类B中的成员函数成为类A的友元函数,这样类B的该成员函数就可以访问类A的所有成员了。当用到友元成员函数时,需注意友元声明和友元定义之间的相互依赖,更一般的讲,必须先定义包含成员函数的类,才能将成员函数设为友元。另一方面,不必预先声明类和非成员函数来将它们设为友元
4)友元的小结
在需要允许某些特定的非成员函数访问一个类的私有成员(及受保护成员),而同时仍阻止一般的访问的情况下,友元是可用的
优点:
可以灵活地实现需要访问若干类的私有或受保护的成员才能完成的任务;
便于与其他不支持类概念的语言(如C语言、汇编等)进行混合编程;
通过使用友元函数重载可以更自然地使用C++语言的IO流库
缺点:
一个类将对其非公有成员的访问权限授予其他函数或者类,会破坏该类的封装性,降低该类的可靠性和可维护性
14.关于下列操作复杂度为O(1)的是()
A.vector中插入元素(动态数组)
B.set中查找元素
C.hash_map中查找元素
D.deque尾部删除元素
答案:CD
解析:
A.vector插入 ,该位置插入后后面的都要改变O(n)
B.Set 底层红黑树 O(logn)
C.Hash_map 底层哈希表 O(1)
D.Deque 尾部可以直接修改O(1)
标签:友元,函数,访问,联编,成员,多态,C++,牛客,刷题 来源: https://blog.csdn.net/weixin_45964837/article/details/122275568