建议用电脑看会比较舒服
看了记得点赞,拒绝白嫖,文明阅读,从你我做起( ˘ω˘ )
选择题:
1.面向对象特征
三大特征:1)封装:作用:①保护数据②模块化
@ 封装
'''
所谓封装就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,
对不可信的进行信息隐藏.封装是面向对象的特征之一,是对象和类概念的主要特性. 简单的说,一个类
就是一个封装了数据以及操作这些数据的代码的逻辑实体。在一个对象内部,某些代码或某些数据可以是
私有的,不能被外界访问。通过这种方式,对象对内部数据提供了不同级别的保护,以防止程序中无关的
部分意外的改变或错误的使用了对象的私有部分。
'''
2)继承:作用:①代码共享,代码复用②实现类的层次结构③当新问题出现,原有方法不能或不能完全解决时,可以对原有程序进行改造
@ 继承
'''
在已有类的基础上创建新的类,新类可以从一个或多个已有类中继承函数和数据(属性和行为),而且
可以重新定义或加进新的数据和函数(属性及方法),从而形成类的层次或等级。其中已有类称为基类
或父类,在它基础上建立的新类称为派生类或子类
'''
3)多态:作用:①接口复用
@ 多态
'''
不同对象收到相同信息时,产生不同的动作
多态就是用一个名字定义不同函数,这些函数执行着不同但又类似的操作,即一个接口多个方法
'''
@ 多态的三个条件:有继承,有虚函数重写,有父类指针指向子类对象。
2.多态的形式
@ 静态联编
'在系统编译时就决定如何实现某一动作' class 要求在编译时就知道调用函数的所有信息:
@ 主要优点:效率高,调用速度快
@ 动态联编
'系统运行时动态实现某一动作,运行时才能确定调用哪个函数'
@ 提供了更好的灵活性
@ 问题抽象性
@ 程序易维护性
3.派生类中基类的成员属性
派生类类型➡ 基类成员⬇ | public | private | protected |
---|---|---|---|
public | public | private | protected |
private | 不可直接访问 | 不可直接访问 | 不可直接访问 |
protected | protectrd | private | protected |
继承方式➡ 基类成员⬇ | public | private | protected | |
---|---|---|---|---|
public | 内部访问 | 可访问 | 可访问 | 可访问 |
对象访问 | 可访问 | 不可访问 | 不可访问 | |
private | 内部访问 | 不可访问 | 不可访问 | 不可访问 |
对象访问 | 不可访问 | 不可访问 | 不可访问 | |
protected | 内部访问 | 可访问 | 可访问 | 可访问 |
对象访问 | 不可访问 | 不可访问 | 不可访问 |
4.类的访问控制属性
public | private | protected | |
---|---|---|---|
类成员 | 可以访问 | 可以访问 | 可以访问 |
友元函数 | 可以访问 | 可以访问 | 可以访问 |
子类 | 可以访问 | 不可以访问 | 可以访问 |
类的实例化对象 | 可以访问 | 不可以访问 | 不可以访问 |
5.静态成员性质
-
静态数据成员:
- 格式:static 类型 成员名;
- 无论创建多少个类的对象,都只有一个静态数据成员的拷贝,从而实现一个类不同对象间的数据共享
- 要在类外初始化, int Student:: school="xxx";要在创建对象前 初始化
- 属于类,属于类对象的集合
- 私有静态不能直接访问,只能通过公有成员函数访问
- 没有this,不能访问,类内共享
-
静态成员函数:
- 属于类的一部分,不属于对象
6.运算符重载
- 参数至少包含一个类对象(或者类对象的引用)
- 不能改变优先级
- 不能改变符号原有特性
- 不能改变操作数
- 不能重载:' . ',' .* ',' ?: ' ,' :: ', ' sizeof '
7.构造函数的性质
- 作用:主要用于为对象分配空间,进行初始化
- 名字必须与类名相同
- 可以有任何类型的参数,但不能指定返回类型,没有返回值
- 可以重载
- 是特殊的成员函数,函数体可以在类内也可以在类外
- 不能被显式调用,只能在定义对象时被程序自动调用
- 不能return值但能通过return终止函数
8.友元函数的性质
- 虽然能访问类的私有成员,但不是类的成员函数
- 不是类成员,不能直接访问对象类的数据成员,没有this
- 类内声明类外实现,实现时不用' 类名::函数名 '
- 友元函数关系是单向的 不能传递,不能继承,不能交换
- 调用数据成员==>对象名.name
- 成员函数调用数据成员==> this.name
9.纯虚函数及抽象类的性质
纯虚函数
- 格式:vitrtal void area()=0(无函数体,=0没有什么用,只是声明这是个纯虚函数而已)
- 只能作为基类,在基类声明,在派生类中实现
- 不能被调用
抽象类
- 一个类至少有一个纯虚函数,则这个类为抽象类
- 只能作为基类,不能建立抽象类对象
- 不能作为参数类型
- 如果派生类没有重定义或实现纯虚函数,那他还是一个抽象类
- 可以定义普通成员函数和虚函数,可以通过派生类来调用
10.析构函数的性质
- 作用:释放对象的内存空间
- 有一个波浪号~,名字与构造函数一样
- 没有参数,没有return值,不能重载
- 在销毁对象时,系统会自动调用析构函数
11.派生类作用
12.虚函数作用
- 为了实现动态多态
-
Ø虚函数的定义是在基类中进行的。它是在基类中需要定义为虚函数的成员函数的声明中以关键字virtual修饰Ø类外实现时不需添加关键字virtualØ在派生类中重新定义时,其函数原型,包括返回类型、函数名、参数个数、参数类型以及参数的顺序都必须与基类中的原型完全相同。
13.函数重载
范 围 | 函数名字 | 参数列表 | virtual 关键字 | |
---|---|---|---|---|
重载 overlode | 相同 | 相同 | 不同 | 可有可无 |
覆盖 override | 不同 | 相同 | 相同 | 一定要有 |
隐藏 hiding | 不同 | 相同 | 不同 | 无论有无 |
相同 | 一定没有 |
(1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4)virtual 关键字可有可无。
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有virtual 关键字。
(1)如果派生类的函数与基类的函数同名,但是参数不同,此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
(2)如果派生类的函数与基类的函数同名,但是参数相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)。
14.STL容器
15.文件流
简答题:
1.派生类不同继承方式的访问属性
2.构造函数及析构函数的特性
构造函数:
- 主要作用:给对象分配空间,进行初始化
- 名字一定要和类名一样
- 可以有任何类型的参数,不能返回指定类型的值
- 可以重载,
- 是特殊的成员函数,函数体可以写在类外也可以写在类内
- 不能被显式调用,定义对象时系统自动调用
析构函数:
- 主要作用:销毁对象时释放内存空间
- 有一个波浪号~,名字要和构造函数一样
- 没有参数,不能return值,不能重载
- 销毁对象时系统自动调用
3.面向对象的三大特征
上面有一模一样的
4.C++的主要特点
1.全面兼容C,并对C的功能做了不少补充
2.增加了面向对象的机制
3.C++编写的程序质量高,可重用性,可扩充性,可维护性,可靠性都有很大提升
4.是更好的C
5.STL容器的优缺点
vector (模型是数组) | list (模型是链表) | deque (数组+链表) | map/ set/ multimap/ multiset (模型是二叉树) | |
---|---|---|---|---|
优点 | ①内存与C完全兼容 ②高效随机访问 ③节省空间 | ①任意插入删除元素时间复杂度小 ②两个容器融合事件复杂度小(常数) | ①高效随机访问 ②内部插入删除效率方便 两端push pop | ①元素会按键值排序 ②查找的时间复杂度是对数 ③可通过键值查找map提供了下标查找 |
缺点 | ①内部插入删除元素代价大 ②动态查询需要申请大量内存做大量拷贝 | ①不支持随机访问 ②比vector占的内存更多 | ①内存占用高 |
Øvector的数据模型就是数组。
Ølist的数据结构模型是链表
Ødeque的数据模型是数组和链表的折衷:
6.什么是多态
程序分析题:
1.构造函数&析构函数的调用顺序
2.拷贝构造函数调用形式
class Book {
public:
enum Language { Chinese, English, Spanish };
Book() {
ISBN_ = 985674;
Lang_ = Chinese;
}
Book(int isbn, Language lang) {
ISBN_ = isbn;
Lang_ = lang;
}
Book(const Book& book) {
ISBN_ = book.ISBN_;
Lang_ = book.Lang_;
cout << "拷贝构造" << endl;
}
Book& operator=(Book& book) {
if (this == &book) {
return *this;
}
else {
ISBN_ = book.ISBN_;
Lang_ = book.Lang_;
}
return *this;
}
void print() {
cout << "book's info: ISBN: " <<ISBN_ << "\tLanguage: " << Lang_ << endl;
}
//======================================以下为测试====================================
void test(Book book) {
cout << "this is a test" << endl;
}
Book test2() {
Book b;
cout << "this is test2 "<<&b << endl;
return b;
}
Book test3() {
Book b=test2();
cout << "this is test3 " << &b << endl;
return b;
}
~Book() {}
friend ostream& operator<<(ostream& os, Book::Language lang);
private:
int ISBN_;
Language Lang_;
};
ostream& operator<<(ostream& os,Book::Language lang) {
if (lang == Book::Chinese) {
os << "Chinese!";
}
else if (lang == Book:: English) {
os << "English!";
}
else if (lang == Book::Spanish) {
os << "Spanish!";
}
return os;
}
int main() {
Book b1(9876723, Book::Spanish);
b1.print();
//=================================================================
cout << "111111111" << endl;
Book b2(b1);//第一种1.用一个已经创好的对象来初始化一个新对象
cout << "222222222" << endl;
Book b3;
b1.test(b3);//2.用值传递来给形参传值的时候
cout << "333333333" << endl;
Book b4;
b4.test2();//3.以值传递的方式返回局部对象都是利用拷贝构造函数的形式
cout << "444444444" << endl;
b4.test3();//
}
3.虚函数的调用方式
程序设计:
1.函数模板
template <class T>
void add(T** a, int row, T& sum){
sum=a[0][0];
for(int i=0;i<row;i++){
for(int j=0;i<row;j++){
sum+=a[i][j];
}
}
sum-=a[0][0];
}
int main(){
int row=5;
int** a=new int*[row];
for(int i=0;i<row;i++){
*a[i]=new int[5];
for(int j=0;j<5;j++){
a[i][j]=i+j;
}
}
int sum=0;
add(a,row,sum)
cout<<"sum==>"<<sum;
}
2.基类、派生类
3.运算符重载
class Book{
public:
enum Language{Chinese,English,Spanish};
Book(){
ISBN_=985674;
Lang_=Language::Chinese;
}
Book(int isbn,Language lang){
ISBN_=isbn;
Lang_=lang;
}
Book& operator=(Book& book){
if(this==&book){
return *this;
}
else{
ISBN_=book.ISBN_;
Lang_=book.Lang_;
}
return *this;
}
void show(){
cout<<"Book's ISBN: "<<ISBN_<<"\tLanguage: "<<Lang_<<endl;
}
friend ostream& operator<<(ostream& os,Book::Language lang);
}
~Book(){}
private:
int ISBN_;
Language Lang_;
};
ostream& operator<<(ostream& os,Book::Language lang){
if(lang==Book::Chinese){
os<<"Chinese!";
}
else if(lang==Book::English){
os<<"English!";
}
else if(lang==Book::Spanish){
os<<"Spanish!";
}
return os;
}
int main(){
Book b1(65789223,Book::Spanish);
b1.show();
}
>>> Book's ISBN: 65789223 Language: Spanish!
4.文本文件读写
class Matrix{
Matrix& Lead(string filename){
ifstream in(filename);
if(!in.is_open()){
cout<<"File can't open !"<<endl;
}else{
string line;
string ww;
while(!in.eof()){
getline(in,line);
if(line!=""&&line!="\n"){
cout<<"line: "<<line;
stringstream ss(line);//可以把string转为int/float
while(getline(ss,ww,' '){
cout<<ww<<"\t";
}
}
}
}
}
};