期末复习c++知识点大回顾,八篇文章让你永不破防(建议收藏)
Posted 行码棋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了期末复习c++知识点大回顾,八篇文章让你永不破防(建议收藏)相关的知识,希望对你有一定的参考价值。
c++期末复习知识点最全整理
目录总览
c++知识点复习最全整理(一)
文章目录
二、类与对象简介
1.类与对象的描述
-
类:具有相同属性和方法的一组对象的集合。简而言之就是一个类别,比如说牛奶、花生、酒等等就是一个是事物的类别。
注: 类是对象的类型,对象是类的实例化,可以把类与int等变量类型作比较,但是不是全部都相似,类还具有方法,就是一些函数功能。
-
类的组成:
-
成员变量
就是在类里面定义的变量
-
成员方法
就是在类里面定义的函数(成员方法)
-
-
-
对象:对象是一个能够看到的实体。
注: 同样可以类比声明变量,声明一个对象,那么这个对象就是一个变量,就是真实存在的。
2.类的特性
-
封装性
尽可能隐蔽对象的内部细节,对外形成一个边界(或者说一道屏障),只保留有限的对外接口使之与外部发生联系。和函数类似,把实现特定功能的代码封装进一个函数里面。
-
继承性
特殊类的对象拥有其一般类的全部属性与服务,称作特殊类对一般类的继承。一个类可以继承另一个类。
-
多态性
在继承中,不同类之间可以具有不同的数据类型或表现出不同的行为。
3.类的定义及成员属性
下面定义一个学生类
class student
{
private:
int id;//学号
char name[20];
int age;
public:
void SetData(int a,char s[],int b)
{
id = a;
name = s;
age = b;
}
}a,b,c;//同时声明三个student对象a,b,c
student d,e; //声明两个student对象d,e
注: 和定义结构体非常类似,可以与结构体相互比较。
以上代码定义了一个学生类,有三个成员变量,分别是id,name,age,可以看到他们的属性为private(私有)。
还有一个成员方法SetData()用来设置成员变量的值,它的属性是public(公有)。
下面是关于成员类型的简介。
注意:
- 类内的成员变量可以相互调用,无论属性是私有还是公有。就好似一家子一样,私有只是对外部而言的。
- 如果未加说明,类中成员默认的访问权限是private,即私有的。
4.对象成员的访问
- 访问一般对象
语法形式:
对象名. 数据成员名
对象名. 成员函数名 (参数表)
- 访问指针对象
语法形式:
对象指针名 -> 数据成员名
对象指针名 -> 成员函数名 (参数表)
注意:
1.从外部访问必须访问的是公有的数据类型,如果访问私有的数据,程序会报错
2.注意一般对象访问和指针对象的访问不一样,和结构体有点类似
下图是较为全面的总结:
5.构造函数和析构函数
构造函数:
- 构造函数的作用是在对象被创建时使用特定的值构造对象,或者说将对象初始化为一个特定的状态。
- 在对象创建时由系统自动调用。
- 如果程序中未声明,则系统自动产生出一个默认形式的构造函数
- 构造函数除了不存在返回值、不可通过对象来调用这样一些特殊之处外,其它方面与普通公有成员函数完全一样。
- 允许为内联函数、重载函数、带默认形参值的函数
析构函数:
- 与构造函数相反,当对象生存期结束时,需要调用析构函数,释放对象所占的内存空间。
- 在对象空间释放时自动调用
- 析构函数也不存在返回值,不可以通过对象来自动调用
- 与构造函数一样,析构函数也是类的一个公有成员函数,它的名称是在类名前加“~”构成,没有返回值,和构造函数不同的是析构函数不接受任何参数。
- 如果程序员没有定义析构函数,系统将自动生成和调用一个默认析构函数。
- 类的析构函数不能重载。 (注意:不能重载呀!!!)
代码演示:
#include<iostream>
using namespace std;
class student
{
private:
int id;//学号
char name[20];
int age;
public:
student(){cout<<"不带参数的构造函数\\n";}
student(int a,char s[],int b)
{
//带参数的构造函数,默认在创建时调用,直接对成员变量进行赋值
id = a;
name = s;
age = b;
}
void SetData(int a,char s[],int b)
{
id = a;
name = s;
age = b;
}
~student()
{
cout<<"析构函数\\n";
}
};
int main()
{
student s1(2,"wang",14),s2;//可以不带参数因为构造函数为重载函数
return 0;
}
6.接口与实现分离
就是把一个面向对象的程序分成多个文件来写
- 类名.cpp文件
- 书写类中成员函数的代码(对代码进行功能扩充)
- main.cpp文件
- 主文件,声明类进行测试
- 头文件需要包含 类名.h 文件
- 类名.h 文件
- 书写类的主体,其中的函数只声明就行,因为代码主体(函数的实现)是在 类名.cpp文件中写的
下面以student类为例:
1.main.cpp文件里面:
#include<student.h>
2.student.h文件里面:
书写类的声明,和成员变量和成员函数的声明。
3.student.cpp文件里面:
#include<student.h>
//主要是书写成员函数的实际代码,进行代码实现
要注意啦!
-
main.cpp 文件中包含的是 类名.h 文件,不是 类名.cpp 文件,以cpp为后缀的文件不能是头文件。
-
包含的类的头文件需要用 “” 括起来,不是尖括号。
“”作用:默认先查找用户自己定义的头文件,然后再查找系统自带的文件,<>是直接从系统文件里面查找对应的文件。
7.条件编译
-
条件编译:
按条件对C++程序的一部分进行编译,其它部分不编译。
-
条件编译的目的:
是使源代码能更迅速、更容易地进行修改,并使目标代码缩短。这样,当程序在不同系统上编译、在同一系统不同编译器上编译或进行不同目的的编译时,减少对程序语句的修改。
7.1. 形式1
#ifdef 标识符
//程序段1
#else
//程序段2
#endif
//意义:若该标识符已被#define命令定义,则编译程序段1,否则编译程序段2
#define DEBUG
#ifdef DEBUG
freopen("1.txt","r",stdin);//程序段1
#else
cout<<"行码棋\\n";//程序段2
#endif //表示程序段2的结束
//上述代码会运行程序段1,因为定义过DEBUG标识符了
7.2.形式2
#ifndef 标识符
//程序段1
#else
//程序段2
#endif //程序段2的结束
//意义:若该标识符没有被#define命令定义,则编译程序段1,否则编译程序段2
7.3. 形式3
#if 表达式
//程序段1
#else
//程序段2
#endif
//意义:若该表达式之值非0 (为真) ,则编译程序段1,否则编译程序段2
注:
- #else 程序段2 这部分可以没有。
- 其中#ifdef等价于#if defined
- #ifndef等价于#if !defined
7.4.应用:预处理器封套(这个可以不看,感觉不太会考呀 )
在头文件中使用“预处理器封套”,从而防止将头文件中的代码多次包含到同一个源代码文件中。由于一个类只能被定义一次,所以使用这样的预处理器指令避免重复定义的错误。
#ifndef 标识符
#define 标识符
…………
// 头文件中的内容
#endif
-
在头文件预处理命令#ifndef和#define中,使用大写字母,并用下划线代替圆点。
例如:tdata.h写成 TDATA_H。time.h写成TIME_H
-
#ifndef的方式依赖于宏名字不能冲突,这不光可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件不会被不小心同时包含。当然,缺点就是如果不同头文件的宏名不小心“撞车”,可能就会导致头文件明明存在,编译器却硬说找不到声明的状况
-
#pragma once则由编译器提供保证:同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。带来的好处是,你不必再费劲想个宏名了,当然也就不会出现宏名碰撞引发的奇怪问题。对应的缺点就是如果某个头文件有多份拷贝,本方法不能保证他们不被重复包含。当然,相比宏名碰撞引发的“找不到声明”的问题,重复包含更容易被发现并修正。
-
方式一由语言支持所以移植性好,方式二 可以避免名字冲突
8.explicit关键字
8.1.介绍
explicit关键字只能用于修饰只有一个参数的类构造函数。
它的作用是表明该构造函数是显式的, 而非隐式的(参数类型不能隐式转换), 跟它相对应的另一个关键字是implicit, 意思是隐藏的,类构造函数默认情况下即声明为implicit(隐式).
定义很难看懂,可以看下面的代码演示:
8.2. 作用
- 注意:必须是只有一个参数才会出现该关键字
#include<bits/stdc++.h>
using namespace std;
class stu
{
private:
int id;
public:
stu(int i)//构造函数只有一个才会起作用
{
id = i;
}
void print()
{
cout<<"id = "<<id<<'\\n';
}
};
int main()
{
stu a = 10; //10隐式转换为构造函数的参数
a.print();
return 0;
}
结果:
id = 10
分析:
当只有一个参数时,stu a = 10;
直接使用赋值语句,其实是创建了stu的对象a,然后10自动隐式转化为传进去的参数,所以能够运行成功
但加上explicit后,情况大变!!!
#include<bits/stdc++.h>
using namespace std;
class stu
{
private:
int id;
public:
explicit stu(int i)
{
id = i;
}
void print()
{
cout<<"id = "<<id<<'\\n';
}
};
int main()
{
stu a = 10;
a.print();
return 0;
}
显示报错,因为加上关键字要求必须是显式的转化,不能隐式转化
以上是关于期末复习c++知识点大回顾,八篇文章让你永不破防(建议收藏)的主要内容,如果未能解决你的问题,请参考以下文章
期末复习c++知识点大回顾,八篇文章让你永不破防(建议收藏)
期末复习c++知识点大回顾,八篇文章让你永不破防(建议收藏)
期末复习c++知识点大回顾,八篇文章让你永不破防(建议收藏)