1.关于函数<返回值类型>,下列表述错误的是:

1
2
3
4
A <返回类型>中有可能包含关键字int
B <返回类型>中有可能包含自定义标识符 //B
C <返回类型>中有可能包含字符 *
D <返回类型>中有可能包含 []

注意:这里的类型可以是预定义类型(如int),复合类型(如double*),用户自定义类型(如枚举类),若返回值只做更新(或设置)等操作,则该函数返回类型是void,函数类型和内置数组不能作为返回值类型

2.程序阅读

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int main()
{
long a = 10, b = 30, l = 0;
if (a % 2 == 0) a++;
for(long m=a;m<=b;m+=2)
if (fun(m))
{
if (l++ % 10 == 0)
cout << endl;
cout << setw(5) << m;
}
return 0;
}
bool fun(long n)
{
int sqrtm = (int)sqrt(n); //sprt:求参数的平方根,并且其参数是一个double类型,返回值也是double类型
for (int i = 2; i <= sqrtm; i++)
if (n % i == 0)
return false;
return true;
}
//11 ,13 ,17 ,19 ,23 ,29

3.假定一个类的构造函数为“A(int i=4,int j=0){a=i;n=j;}”,则执行"A x(1);"语句后,x.a和x.b的值分别为()

1
2
3
4
5
A 10
B 14
C 40
D 41
//带默认的构造函数,对应实参没有值时就采用形参值。调用构造函数时,i=1,不采用默认值,而只有一个参数,j采用默认值0,因此a=1,b=0;

4.派生类构造函数的成员初始化列表中,不能包含的初始化项是:

A:基类的构造函数

B:基类的子对象 //B

C:派生类的子对象

D:派生类自身的数据成员

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//因为在C++中,构造函数不能被继承,因此,派生类的构造函数必须通过调用基类的构造函数来初始化基类子对象(在派生类初始化列表直接初始化基类的成员,被称为“越级初始化”)
class A{
protected:
int n;//基类的子对象
public:
A();
A(int temp):n(temp){}
};
class B:class A
{
public:
// B(int temp):n(temp){} 对基类子对象进行初始化“越级初始化”
//但是可以"越级赋值"
B(int temp){n=temp};
};
int main()
{
B(1);
return;
}

5.多继承派生类构造函数构造对象时,(B)被最先调用

A:派生类自己的构造函数

B:虚基类的构造函数

C:非虚基类的构造函数

D:派生类中子对象类的构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
//先调用(构造函数)所有基类的构造函数;再调用派生类中子对象类的构造函数(如派生类的子对象)(在一个类中内嵌另一个类的对象作为数据成员,称为类的组合。该内嵌对象称为对象成员,也称为子对象。)
;最后调用派生类构造函数
//`注意`:处于同一层次的各基类构造函数的调用顺序取决于派生类所指定的的基类顺序,与派生类构造函数中所定义的成员函数初始化无关
class Base1
{
public:
Base1(int i){
a=i;
cout<<"Constructing Base1 a="<<a<<endl;
}
private:
int a;
};
class Base2
{
public:
Base1(int i){
b=i;
cout<<"Constructing Base1 b="<<b<<endl;
}
private:
int b;
};

class Derivedclass:public Base1,public Base2
{
public:
Derivedclass(int i,int j,int k);
private:
int d;
};
Derivedclass::Derivedclass(int i,int j,int k):Base2(i),Base1(j) //先调用Base1再调用Base2,虽然在初始化列表顺序中,先调用了Base2再调用了Base1,但是根据前文介绍先调用Base1
{
d=k;
cout<<"Constructing Derivedcalss d="<<d<<endl;
}

int main()
{
Derivedcalss x(4,5,6);
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
//如果派生类有一个虚基类作为祖先类,那么在派生类构造函数的初始化列表中需要对虚基类构造函数的调用,如果未列出则表明用的是虚基类的无参构造函数
//注意:不管初始化列表中次序如何,对虚基类构造函数的调用总是先于普通基类的构造函数(虚基类的唯一副本只被初始化一次)
例如;
带有基类的多层派生类构造函数的成员初始化列表中都要列出虚基类的构造函数,这样将对虚基类的子对象初始化1
class Base1
{
public:
Base1(){cout<<"Constructing Base1"<<endl;
}
class Base2
{
public:
Base1(){cout<<"Constructing Base2"<<endl;
}

//派生类
class Derived1:public Base2,virtual public Base1
{
public:
Derived1(){cout<<"Constructing Derived1"<<endl;
}

class Derived2:public Base2,virtual public Base1
{
public:
Derived1(){cout<<"Constructing Derived2"<<endl;
}

class Derived3:public Derived1,virtual public Derived2
{
public:
Derived1(){cout<<"Constructing Derived3"<<endl;
}

int main()
{
Derived3 obj;
return0;
}

//运行结果:
Constructing Base1
Constructing Base2
Constructing Derived2
Constructing Base2
Constructing Derived1
Constructing Derived3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//有多个子对象的类的构造函数如何定义
class X {
类名1 对象成员名1;
类名2 对象成员名2;

类名n 对象成员名n;
};
//则类X的构造函数应该这样定义
X∷X(参数表0):对象成员名1(参数表1),对象成员名2
(参数表2),…,对象成员名n(参数表n)
{
类X的构造函数体
}
//参数表1、参数表2 、… 、参数表n的数据,一般来自参数表0
/*
调用构造函数D∷D( )时:
首先按各对象成员在类定义中的顺序依次调用它们的构造函数,对这些对象初始化。
最后再执行D∷D( )的函数体。
*/
//撤销类D的对象d1时,调用析构函数的调用顺序与调用构造函数的顺序相反。

6.程序阅读题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
using namespace std;
class Base
{
public:
Base(int i) { cout << i; }
~Base () { }
};
class Base1: virtual public Base
{
public:
Base1(int i, int j=0) : Base(j) { cout << i; }
~Base1() {}
};
class Base2: virtual public Base
{
public:
Base2(int i, int j=0) : Base(j) { cout << i; }
~Base2() {}
};
class Derived : public Base2, public Base1
{
public:
Derived(int a, int b, int c, int d) : mem1(a), mem2(b), Base1(c),
Base2(d), Base(a)
{ cout << b; }
private:
Base2 mem2;
Base1 mem1;
};
void main() { Derived objD (1, 2, 3, 4); }

//14302012
CSDN_1683445174034

7.不能在类声明中给成员赋值

1
2
3
4
5
6
7
8
9
class  abc 
{
private:
char a='q'; //错误
int b=33; //错误
public:

};
// C++规定,只有在对象定义之后才能给数据成员赋初值

注意:声明了一个类便声明了一种类型,这时没有给它分配存储空间,只有定义了对象后,系统才为对象分配存储空间

8.数据成员是按照它们在类中声明的顺序进行初始化的,与它们在成员初始化列表中列出的顺序无关

1
2
3
4
5
6
7
8
9
10
11
12
#include<iostream>
using namespace std;
class D {
int mem1;
int mem2;
public:
D(int i):mem1(i),mem2(mem1+1)
{ cout<<"mem1: "<<mem1<<endl;
cout<<"mem2: "<<mem2<<endl; } };
void main()
{ D d(15); }
//运行结果为 mem1: 15 mem2: 16
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include<iostream>
using namespace std;
class D {
int mem1;
int mem2;
public:
D(int i):mem2(i),mem1(mem2+1)
{ cout<<"mem1: "<<mem1<<endl;
cout<<"mem2:"<<mem2<<endl; } };
void main()
{ D d(15); }
//注意:运行结果为 mem1: 858993459 mem2: 15
//初始化过程:
1.mem1=mem2+1=随机数
2.mem2=i=15

9.在一个类中定义了全部是默认参数的构造函数后, 不能同时再声明无参数的默认构造函数,或其他重载构造函数。

1
2
3
4
5
6
7
//在一个类中有以下构造函数的声明:
Box(int h=10,int w=10,int len=10);
//就不能再声明无参数的构造函数:
Box( );
//否则,如用下面的语句建立对象
Box box1;
//box1不知道调用哪个构造函数,会产生二义性

10.对象数组

定义一维对象数组的格式如下:

类名 数组名[下标表达式];

例如:

exam ob[4];

说明:共建立了四个对象,即每一个数组元素是一个对象(即ob[0]、ob[1]、ob[2]、 ob[3]),共调用了4次构造函数。
1
2
3
4
5
6
7
8
9
10
11
12
13
#include<iostream.h>    
class exam{
int x;
public:
exam( ){ x=123;}
exam(int n) { x=n;}
int get_x() { return x; }};
int main()
{ exam ob[4]={55,66}; //ob[0]和ob[1]调用带参构造函数,ob[2]和ob[3]调用无参构造函数
int i;
for (i=0;i<4;i++) cout<<ob[i].get_x()<<' ';
return 0; }
//55 66 123 123

11.对象指针

声明对象指针的一般语法形式为:

类名* 对象指针名;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<iostream> 
using namespace std;
class Rectangle{
public:
void setRec(int len,int wid)
{ length=len; width=wid; }
void disp() { cout<<length<<" "<<width<<endl; }
private:
int length,width; };
int main()
{ Rectangle rec ; //定义类Rectangle 的对象rec
Rectangle *pr; //定义pr为指向类Rectangle的对象指针变量
rec.setRec(20,30); //调用对象rec中的函数setRec
pr=&rec; // 将对象rec的起始地址赋给pr
pr->disp(); // 调用pr所指向的对象rec中的函数disp;用对象指针访问对象成员时,不能用“.”操作符,而应使用“-> ”操作符
return 0; }

程序的运行结果如下:
20 30

12.静态数据成员的应用(在类Student中,声明数据成员count,希望每定义一个对象count加1,从而达到统计学生的总数的目的。)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include<iostream.h>      
class Student {
int count; //声明数据成员count,表示学生数,用于统计学生的总数
public:
Student( ) { count++; } // 构造函数,希望每定义一个学生对象,学生数count加1
void print( ) // 成员函数,显示当前学生数
{ cout<<"count= "<< count <<endl; }
};
main( )
{ int count=0;
Student Stu1; //定义第1个学生对象Stu1,第1次调用构造函数
Student Stu2; //定义第2个学生对象Stu2,第2次调用构造函数
Stu1.print();
Stu2.print(); //希望打印的结果为:count=2 count=2 实际打印的结果为: count= -858993459 count= -858993459
return 0; }
//注意:出现错误的原因是:
// count Stu1.count Stu2,count 三者是独立的,互不相干
// 一个学生对象的count仅仅属于这个学生对象,而不是所有学生对象所共享的,因此count不能表示所有学生的总人数。
// 解决方法: 为了实现同一个类的多个对象之间的数据共享,C++提出了静态数据成员的概念。
更改后为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<iostream.h>      
class Student {
static int count; //声明静态数据成员count,被所有的对象共享, 用于统计学生的总数
public:
Student(){ count++;} //构造函数,每创建一个学生对象,学生数count加1
void print()
{ cout<<"count= "<< count <<endl; }
};
int Student::count=0; //给静态数据成员count赋初值0
int main( )
{ Student Stu1; //定义第1个学生对象Stu1,第1次调用构造函数Student Stu2; //定义第2个学生对象Stu1,第2次调用构造函数
Stu1.print();
Stu2.print();
return 0; }
  1. 静态数据成员属于类(准确地说,是属于类中一个对象集合),而不像普通数据成员那样属于某一对象,因此可以使用“类名∷”访问静态的数据成员。用类名访问静态数据成员的格式如下:

​ 类名::静态数据成员名

  1. 静态数据成员初始化应在类外单独进行,而且应在定义对象之前进行。一般在主函数main 之前,类声明之后的特殊地带为它提供定义和初始化(如果末对静态数据成员赋初值,则编译系统会自动赋予初值0)
  2. 公有静态数据成员可以在对象定义之前被访问
  3. 公有静态数据成员可通过对象进行访问

13.调用拷贝构造函数的时机

下列情况中,哪种情况不会调用拷贝构造函数

1
2
3
//将类的一个对象赋值给该类的另一个对象时,不用调用拷贝构造函数,是用赋值运算符重载实现的:
MyClass a(b);
或者 MyClass a=b;//就会调用 赋值重载 operator=来赋值,对象a已经存在了,调用普通的赋值运算符就可以了,不用再调用构造函数
  • 程序中需要创建一个新的对象,并用另一个对象对它初始化
  • 函数的参数为类的对象
  • 函数的返回值是类的对象

14.下列关于对象的描述错误的是

15.程序阅读题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
using namespace std;
class point
{
public:
static int number;
point(){number++;}
~point(){number--;}
};
int point::number=0;
void main()
{
point *ptr;//指针不会调用构造函数和析构函数,只是定义了一个指针,没有申请内存
point A,B;// +2
{
point *ptr_point=new point[3];//使用new创建对象时,申请分配内存,调用构造函数 +3
ptr=ptr_point;
}
point C; // +1
delete[]ptr; //释放空间会调用构造函数 -3
cout<<point::number<<endl; //3
}
//Point *ptr_point = new Point[3];动态创建3个对象实例,调用默认构造函数3次。而ptr=ptr_point语句让ptr指向ptr_point动态数组,不会调用构造函数。ptr_point指针本身被释放的时,不会销毁指向的实例。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
using namespace std;
class CT {
public :
CT () {
cout << "Default constructor called" << endl;
}
CT (const CT &rhs) {
cout << "Copy constructor called" << endl;
}
};
int main ()
{
CT ct;
CT *p;
cout << "Step1" << endl;
p = new CT; //动态创建一个对象实例,调用默认构造函数1次
CT ct3 (*p);
cout << "Step2" << endl;
delete p;
return 0;
}


//Default constructor called
//Step1
//Default constructor called
//Copy constructor called
//Step2

16.理解int(* p)[3]和int *p[3]的意思

1
2
3
4
5
6
7
8
9
10
11
12
13
//下列程序输出结果是:
#include <iostream>
using namespace std;
void main()
{
int n[][3]={10,20,30,40,50,60};
int(*p)[3];
p=n;
cout<<p[0][0]<<","<<*(p[0]+1)<<","<<(*p)[2]<<endl; //10,20,30
}
//int(*p)[3]数组指针,p是一个指针,指向一个有3个变量的一维数组
//int *p[3]指针数组,p是一个有三个元素的数组,每个元素的类型都是整形指针
//因为定义数组[]的优先级高于定义指针*的优先级

17.程序阅读

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include<iostream>
using namespace std;
class Base
{
protected:
Base() { cout << 'A'; } //1
Base(char c) { cout << c; }
};
class Derived :public Base
{
public:
Derived(char c) { cout << c; } //派生类构造函数中无基类参数表则调用无参的基类构造函数 //2
};
int main()
{
Derived d1('B');
return 0;
}
//AB

18.带有基类的多层派生类构造函数的成员初始化列表中都要列出虚基类的构造函数,这样将对虚基类的子对象初始化()

19.程序阅读

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include<iostream>
using namespace std;
class A
{
public:
A(int i) :a(i)
{
cout << "A:constructor called." << endl;
}
~A()
{
cout << "A:Destructor called." << endl;
}
void Print()
{
cout << a << endl;
}
int Geta()
{
return a;
}
private:
int a;
};
class B :public A
{
public:
B(int i = 0, int j = 0) :A(i),a(j), b(i + j)
{
cout << "B:Constructor called." << endl;
}
~B()
{
cout << "B:Destructor called." << endl;
}
void Print()
{
A::Print();
cout << b << ',' << a.Geta()<< endl;
}
private:
int b;
A a;
};
int main()
{
B b1(8), b2(12, 15);
b1.Print();
b2.Print();
return 0;
}

/*
A:constructor called.
A:constructor called.
B:Constructor called.
A:constructor called.
A:constructor called.
B:Constructor called.
8
8,0
12
27,15
B:Destructor called.
A:Destructor called.
A:Destructor called.
B:Destructor called.
A:Destructor called.
A:Destructor called.
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include<iostream>
using namespace std;
class test
{
private:
int x;
public:
test(int i=0):x(i){}
virtual void fun1()
{
cout << "text::x" << x << endl;
}
};
class ft :public test
{
int y;
public:
void fun1()
{
cout << "ft::y=" << y << endl;
}
ft(int i=2):test(i),y(i){}
};
int main()
{
ft ft1(3);
void(test:: * p)();
p = test::fun1; //p指向fun1函数
(ft1.* p)(); //(ft1.*p)实际上就算调用ft1对象的fun1()函数
return 0;
}
//ft::y=3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include<iostream>
using namespace std;
class A
{
public:
virtual ~A()
{
cout << "A::~A() called" << endl;
}
};
class B :public A
{
char* buf;
public:
B(int i)
{
buf = new char[i];
}
virtual ~B()
{
delete[]buf;
cout << "B::~B() called" << endl;
}
};
void fun(A* a)
{
delete a;
}
int main()
{
A* a = new B(10);
fun(a);
return 0;
}
//B::~B() called
//A::~A() called

20.运算符的使用

插入符<< 和 提取符>>

下列关于C++程序中使用提取符和插入符的输入/输出语句的描述中,错误的是(C )

注意:操作数是指,参与运算操作的源数据,通常由指令的地址部分标识出来 提取符和插入符都是单目运算符

不能用浮点数操作的运算符

1.& 双目

2.%

3.== !=

类型转换运算符的使用

注意:类型转换运算符通常用于赋值中

21.返回类型

关于函数中的<返回类型>,下列表述中错误的是( B )

注意:<返回类型>又称函数类型,表示一个函数所计算(或运行)的结果值类型,这里的类型可以是预定义类型(如int),复合类型(如double*),用户定义类型(如枚举类),若返回值只做更新(或设置)等操作,则该函数返回值类型为void类型,函数类型和内置数组不能作为返回类型,但类类型可以被直接返回

22.虚函数 下列关于虚函数的说明中,正确的是( B )

注意:1.虚函数是被virtual关键字修饰的成员函数,且不能是静态成员函数
2.实现多态性之后不再定义声明,继承也为虚函数
3.动态联编只能通过指针或引用标识对象操作虚函数

23.函数模板,关于函数模板,描述错误的是( )。

注意:成员函数模板当编译器遇到程序中对函数模板的调用是,由编译器实例化为可执行的模板函数

24.已知fun(int)是类Test的公有成员函数,p是指向成员函数fun()的指针,采用(D)是正确的:

注意:首先fun是类Text的成员函数,因此在使用时需要加上类名,否则当类外有同名的fun函数的时候,p将指向类外的fun函数。其次,fun的函数名代表的是2函数的首地址,用首地址赋值给指针变量是正确的。而B,是缺少实参的函数调用

25.程序设计结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
using namespace std;
#include<iostream>
void main()
{
struct num {
int x;
int y;
}sa[] = { {2,32},{8,16},{4,48} };
struct num* p = sa + 1;
int x;
x = p->y / sa[0].x * ++p->x; //先计算p->y=16 sa[0].x=2 所以p->y/sa[0].x=8 再计算++p->x 先算p->x=8再++就x=9 最后计算 8*++p->x为8*9=72
cout << "x=" << x << "p->x=" << p->x << endl; //x=9 p->x=72
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream.h>
void main()
{ int x=3,y=3;
switch(x%2)
{
case 1: switch (y)
{ case 0:cout<<"first\t"; //\t相当于键盘上的Tab键,通常宽度相当于8个空格的位置
case 1:cout<<"second\t";break;
default: cout<<"hellow\t";
}
case 2:cout<<"third\n";
}

//hellow third