目录
一、静态成员
1.下列关于this指针的叙述中,正确的是 D
A.任何与类相关的函数都有this指针
B.类的成员函数都有this指针
C.类的友元函数都有this指针
D.类的非静态成员函数才有this指针2.以下说法正确的是(C)。
A.在静态成员函数中可以调用同类的其他任何成员函数
B.const成员函数不能作用于非const对象
C.在静态成员函数中不能使用this指针
D.静态成员变量每个对象有各自的一份3.静态成员函数没有: B
A. 返回值
B. this指针
C. 指针参数
D. 返回类型4.下面对静态数据成员的描述中,正确的是 A
A. 静态数据成员是类的所有对象共享的数据
B. 类的每个对象都有自己的静态数据成员
C. 类的不同对象有不同的静态数据成员
D. 静态数据成员不能通过类的对象调用,只能通过“类名::标识符”调用5.以下说法正确的是?C
A.在静态成员函数中可以调用同类的其他任何成员函数
B.const成员函数不能作用于非 const 对象
C.在静态成员函数中不能使用 this 指针
D.静态成员变量每个对象有各自的一份
注:静态成员函数没有当前对象,没有this指针,只能直接访问静态成员,而不能访问非静态成员(包括静态成员变量和静态成员函数) 第六题同理
6.已知f1和f2是同一类的两个成员函数,但f1不能直接调用f2,这说明 B
A f1和f2都是静态函数
B f1是静态函数,f2不是静态函数
C f1不是静态函数,f2是静态函数
D f1和f2都不是静态函数7.下面有关静态成员函数的描述中,正确的是 B
A 在静态成员函数中可以使用this指针
B 在建立对象前,就可以为静态数据成员赋值
C 静态成员函数在类外定义是,要用static前缀
D 静态成员函数只能在类外定义二、友元
1.不属于类的成员函数的是(C) 。
A.构造函数
B.析构函数
C.友元函数
D.复制构造函数
2.对于以下关于友元的说法 D
A. 如果函数fun被声明为类A的友元函数,则该函数成为A的成员函数
B. 如果函数fun被声明为类A的友元函数,则该函数能访问A的保护成员,但不能访问私有成员
C. 如果函数fun被声明为类A的友元函数,则fun的形参类型不能是A。
D. 以上答案都不对3.友元的作用是 A
A. 提高程序的运用效率
B. 加强类的封装性
C. 实现数据的隐藏性
D. 增加成员函数的种类4.下面关于友元的描述中,错误的是: D
A. 友元函数可以访问该类的私有数据成员
B. 一个类的友元类中的成员函数都是这个类的友元函数
C. 友元可以提高程序的运行效率
D. 类与类之间的友元关系可以继承5.下面对静态数据成员的描述中,正确的是 D
A.静态数据成员可以在类体内进行初始化
B.静态数据成员不可以被类的对象调用
C.静态数据成员不能受private控制符的作用
D.静态数据成员可以直接用类名调用
6.以下关于友元的说法哪个是不正确的? B
A.一个类的友元函数可以访问类对象的私有成员
B.友元类关系是相互的,即若类A是类B 的友元,类B也是类A的友元
C.在一个类中可以将另一个类的成员函数声明为友元
D.类之间的友元关系不能传递
注:1.友元关系是单向的
如果声明B类是A类的友元,B类的成员函数就可以访问A类的私有和保护数据,但A类的成员函数却不能访问B类的私有、保护数据。
2.友元关系不能传递,不被继承!
7.已知类A是类B的友元,类B是类C的友元,则:D
A.类A一定是类C的友元
B.类C一定是类A的友元
C.类C的成员函数可以访问类B的对象的任何成员
D.类A的成员函数可以访问类B的对象的任何成员
三、常类型
1.下列哪一种情况下,类的复制构造函数不会被调用 A
A.用类的一个对象赋值给另一个对象时
B.当用类的一个对象去初始化该类的另一个对象时
C.如果函数的形参是类的对象,调动函数时,进行形参和实参结合时
D.如果函数的返回值是类的对象,函数执行完成返回调用者时
2.已知类A中的一个成员函数说明为void fun(A &a);,则A &a的含义是( )
A.将a的地址值赋给变量fun
B.指向类A的指针为a
C.a是类A的对象引用,用来做函数fun()的形参
D.变量A与a按位相与运算后作为函数fun()的参数
3.关于常成员的描述中,哪个是错误的? C
A.常成员是用关键字const说明的
B.常成员有常数据成员和常成员函数两种
C.常数据成员的初始化是在类体内定义它时进行的
D.常数据成员的值是不可以改变的
4.由于常对象不能被更新,因此 A
A 通过常对象只能调用它的常成员函数
B 通过常对象只能调用静态成员函数
C 常对象的成员都是常成员
D 通过常对象可以调用任何不改变对象值的成员函数
5.以下对类A的定义中正确的是(B) (2分)
class A{private:int v;public : void Func(){}}
class A{private : int v;A *next;};
class A{int v;public:void Func();};A::void Func(){}
class A{int v;public: A next;void Func(){ }};
注:A.class A{private:int v;public : void Func(){}};C.class A{int v;public:void Func();};void A::Func(){}
D.class A{int v;public: A *next;void Func(){ }};
6.给定以下类声明,哪个成员函数可能改变成员变量data?(D)
class A {
public:
void f1 (int d);
void f2 (const int &d);
void f3 (int d) const;
private:int data;
};A.f1
B.f2
C.f3
D.f1和f27.若有以下类W说明,则函数fConst的正确定义是 A
class W{
int a;
public:
void fConst(int &) const;
};
A.void W::fConst(int &k ) const { k = a;}
B.void W::fConst(int &k ) const { k = a++;}
C.void W::fConst(int &k ) const { cin>> a;}
D.void W::fConst(int &k ) const { a = k;}
注: 常函数能修改传入自身的形参以及内部定义的局部变量,但常成员函数不能用来更新类的任何成员变量,也不能调用类中未用const修饰的成员函数,只能调用常成员函数。
补:
(1) 常成员函数:在一个普通成员函数后面加上const修饰,就是常成员函数;
(2)非const对象可以调用常函数,也能调用非常函数。但是常对象只能调用常函数,不能调用非常函数(常对象也包括常指针和常引用)
(3)普通成员函数才有常函数。C++中构造函数,静态成员函数,析构函数,全局成员函数都不能是常成员函数。
四、对象数组
1.point (*p)[3]; point是类名,p为指向对象数组的指针
2.point *p[3]; point是类名,p为对象指针数组,每个数组元素都是指向point对象的指针变量
3.对象数组中的元素必须是同一个类的对象
4.生成对象数组时,将针对每个数组元素按其下标的排列顺序依次调用一个构造函数。
5.定义对象数组时可以直接初始化,也可以通过赋值语句进行赋值。
6.对象数组在定义过程中进行元素初始化时调用有参构造函数;如果只定义而不进行初始化,则调用无参构造函数。
7.对数组元素赋值时(用赋值语句),系统先调用有参构造函数创建无名对象,并将其值赋给响应对象数组元素,最后再调用析构函数将无名释放。
8.简单程序题:PTA 通过指针,输出对象数组的数据
设计一个类,主函数中建立一个对象数组,输入5个学生数据(学号、成绩),用对象指针指向数组首元素,输出5个学生的数据。
输入格式:
输入5个学生数据(学号、成绩),学号为不超过10000的正整数,成绩为0-100的正整数。
输出格式:
按顺序输出学生的学号和成绩,每行显示一个学生的信息。
输入样例:
在这里给出一组输入。例如:
101 90 102 80 103 70 104 60 105 50
输出样例:
在这里给出相应的输出。例如:
101 90 102 80 103 70 104 60 105 50
代码:
#include<iostream>
using namespace std;
class Student{
public:
void Set_student(int num,int score){
n=num;
s=score;
}
void display(){
cout<<n<<" "<<s<<endl;
}
private:
int n;
int s;
};
int main(){
Student stu[5];
int num,score;
int i;
for(i=0;i<5;i++){
cin>>num>>score;
stu[i].Set_student(num,score);
}
Student (*p) = stu;//定义对象指针指向对象数组
for(i=0;i<5;i++,p++){
p->display();
}
return 0;
}
五、复制构造函数
1.拷贝(复制)构造函数的作用是 C
A 进行数据类型的转换
B 用对象调用成员函数
C 用对象初始化对象
D 用一般类型的数据初始化对象2.下列情况中,不会调用复制构造函数的是 D
A 用一个对象去初始化同一类的另一个新对象时
B 函数的返回值是类的对象,函数执行返回调用时
C 函数的形参是类的对象,调用函数进行形参和实参结合时
D 函数的返回值是类的对象的引用,函数执行返回调用时3.通常,拷贝构造函数的参数是 C
A 某个对象名
B 某个对象的成员名
C 某个对象的引用名
D 某个对象的指针名
六、运算符重载
1.下列运算符不允许重载(5个),以外,C++中的所有运算符都可以重载
. (成员), *(指针) , ::(域运算符) , ?:(三目运算符),siezof(容量度);
而下列只能通过成员函数来重载(4个);
=(赋值),[],(),->(指向并访问)在C++中,=、[]、()、->以及所有的类型转换运算符只能作为成员函数重载。
2.对“<<”和“>>”重载的函数形式如下:
istream & operator >> (istream &, 自定义类 &);
ostream & operator << (ostream &, 自定义类 &);
即重载运算符“>>”的函数的第一个参数和函数的类型都必须是istream&类型,第二个参数是要进行输入操作的类。重载“<<”的函数的第一个参数和函数的类型都必须是ostream&类型,第二个参数是要进行输出操作的类。因此,只能将重载“>>”和“<<”的函数作为友元函数或普通的函数,而不能将它们定义为成员函数。3.若要对类BigNumber中重载的类型转换运算符long进行声明,下列选项中正确的是 A
A operator long() const;
B operator long(BigNumber);
C long operator long() const;
D long operator long(BigNumber);4.在C++的类中重载二元运算符为成员运算符时,只能指定 A
A 一个参数
B 两个参数
C 三个参数
D 不能指定参数5.在重载一个运算符为成员函数时,其参数表中没有任何参数,这说明该运算符是 B
A 后缀一元运算符
B 前缀一元运算符
C 无操作数的运算符
D 二元运算符注:为了区分前++和后++,后++和后--重载时增加一个整形形参(int)
6.下列关于运算符重载的描述中,正确的是 A
A 运算符重载为成员函数时,若参数表中无参数,重载的一定是一元运算符
B 一元运算符只能作为成员函数重载
C 二元运算符作为非成员函数重载时,参数表中只有一个参数
D C++中可以重载所有的运算符注:B.比如负号的重载就既可以是友元函数重载,又可以是成员函数重载
7.关于插入运算符<<的重载,下列说法不正确的是 B
A 运算符函数的返回值类型是ostream &。
B 重载的运算符必须定义为类的成员函数。
C 运算符函数的第一个参数的类型是ostream&。
D 运算符<<函数有两个参数。注:B 重载的运算符<<要定义成友元函数或者普通的函数,但一定不是成员函数
经典栗子:
复数类:
题目描述
请利用运算符重载实现复数类,该复数类具有构造,+,-,×和输出流插入运算符重载功能。
输入描述
每个测试案例有两行输入,分别代表两个复数的实部和虚部,用double型表示
输出描述
对于每个测试案例输出5行,分别代表两个复数和它们的+-×结果。结果小数点后保留2位。
样例输入
1.2 3.5 3 -2样例输出
1.20+3.50i 3.00-2.00i 4.20+1.50i -1.80+5.50i 10.60+8.10i
代码:
#include<iostream>
#include<fstream>
#include<iomanip>
using namespace std;
class Complex{
public:
Complex(double real,double imag):i_real(real),i_imag(imag){}//构造函数
Complex operator+(const Complex &rhs) const;//成员函数,复数加法
friend Complex operator-(const Complex &z1,const Complex &z2);//友元函数,复数减法
Complex operator*(const Complex &rhs);//成员函数,复数乘法
friend ostream & operator<<(ostream &os,const Complex &rhs);//友元函数,输出复数
private:
double i_real;
double i_imag;
};
Complex Complex::operator+(const Complex &rhs) const{
return Complex(i_real+rhs.i_real,i_imag+rhs.i_imag);
}
Complex operator-(const Complex &z1,const Complex &z2){
return Complex(z1.i_real-z2.i_real,z1.i_imag-z2.i_imag);
}
Complex Complex::operator*(const Complex &rhs){
return Complex(i_real*rhs.i_real-i_imag*rhs.i_imag,i_real*rhs.i_imag+i_imag*rhs.i_real);
}
ostream & operator<<(ostream &os,const Complex &rhs){
if(rhs.i_imag<0){
os<<fixed<<setprecision(2)<<rhs.i_real<<rhs.i_imag<<"i"<<endl;
}
else{
os<<fixed<<setprecision(2)<<rhs.i_real<<"+"<<rhs.i_imag<<"i"<<endl;
}
return os;
}
int main(){
double r,m;
cin>>r>>m;
Complex c1(r,m);
cin>>r>>m;
Complex c2(r,m);
cout<<c1;
cout<<c2;
Complex c3(0,0);
c3=c1+c2;
cout<<c3;
c3=c1-c2;
cout<<c3;
c3=c1*c2;
cout<<c3;
return 0;
}
运行结果:
参考大佬博客: