实例
编译器:CodeBlocks
本套课程的设计目的是:
- 理解C++基本语法
- 具备面向对象的程序设计思想
- 可以独立设计C++项目的能力
1. 第一部分:入门
– 1.1 C++ 简介
C++在C语言基础上面向对象设计,体现在类的机制,也叫作带类的C语言;
1.1.1 C到C++
C语言结构体:
struct类型,成员变量,变量A
'
struct stu
{
int num;
char sex;
int math_score;
int en_score;
int c_score;
};
int main()
{
struct stu A;
return 0;
}
运行
C++结构体:
class定义,包含成员变量(属性),函数(方法)两部分;
'
class stu
{
int num;
char sex;
int math_score;
int en_score;
int c_score;
int total_score()
{
return math_score+en_score+c_score;
};
};
int main()
{
class stu A;
return 0;
}
运行
– 1.2 环境设置和配置
– 1.3 第一个Hello World 程序
#include<iostream>
using namespace std;
int main()
{
cout<<"Nice to meet you!"<<endl;
return 0;
}
1.3.1 第一个程序解读
头文件包含 iostream 标准库
声明使用 std 命名空间
main() 主函数体
{
cout输出,endl换行
}
1.3.2 命名空间
把相同的名字都放到不同的空间,解决多个模块命名冲突的问题
例如标准C++库提供的对象都存放在std这个标准命名空间中,比如cin、cout、endl
必须要声明命名空间,并且包含头文件在前,声明使用的名字空间在后
不同写法 1 2 3
#include<iostream>
using namespace std;
int main()
{
cout<<"Nice to meet you!"<<endl;
return 0;
}
#include<iostream>
int main()
{
//使用域限定符::
std::cout<<"Nice to meet you!"<<std::endl;
return 0;
}
#include<iostream>
//使用using和域限定符
using std::cout;
using std::endl;
int main()
{
cout<<"Nice to meet you!"<<endl;
return 0;
}
1.3.3 输入输出
不需要指定输入或输出的变量类型,这源于cin和cout本身是一个类,而非函数、甚至关键字
1. cout输出流的使用:
cout<<"Hello"<<endl<<"www.dotcpp.com"<<endl;
cout<<"Hello"<<" www.dotcpp.com";
Hello
www.dotcpp.com
Hello www.dotcpp.com
2. cin输入流的使用:
#include<iostream>
using namespace std;
int main()
{
int a;
cout<<"input number:"<<endl;
cin>>a;
cout<<"Get "<<a<<endl;
return 0;
}
cin也可以连续接收多个变量
int a,b;
cin>>a>>b;
input number:
24
Get 24
2 基本语法
– 2.1 数据类型和变量
1.C++中的数据类型
int、char、float、double
分别表示整形、字符型、单精度和双精度类型
#include<iostream>
using namespace std;
int main()
{
int num;//学生学号
char sex;//性别
double score1;//科目一成绩
double score2;//科目二成绩
double score3;//科目三成绩
cout<<"Please input student's ID、‘M’ or ‘W’、score1、score2 and score3"<<endl;
cin>>num>>sex>>score1>>score2>>score3;
cout<<"ID:"<<num<<" "<<sex<<" Total score is:"<<score1+score2+score3<<endl;//输出该学生信息及总成绩
return 0;
}
运行结果
bool类型
布尔类型是一种逻辑值,关键字类型为bool,定义出来的变量只有true和false两个,分别表示真和假两个值,在内存上一般只占一个字节
#include<iostream>
using namespace std;
int main()
{
int a=9;
int b=1;
bool r;//定义布尔类型变量r
r = a>b;
cout<<r<<endl;
cout<<"bool size is:"<<sizeof(r)<<endl;
return 0;
}
2.C++算数运算符实例讲解
算数运算符(+、-、*、/、%)有5种
%是求模,取余的意思,比如20%8的结果就是4,且%两端的运算数必须是整数。
3.C++bool类型实例讲解
在C语言中,我们讲到逻辑值的概念,即通过判定数值1为真,0为假,但没有专门的类型支持。在C++中,有了明确的类型支持,即bool类型,即只能表示false(假)或true(真),这种类型只占一个字节大小,大家可以尝试定义这种类型的变量并赋值和输出,如:
#include<iostream>
using namespace std;
int main()
{
bool a=true;
bool b=false;
cout<<a<<endl<<b<<endl;
return 0;
}
输出 1
0
– 2.2 运算符和表达式
4.C++自增++和自减–运算符实例讲解
自增运算符(++)和自减运算符(–)都是单目运算符,与C语言类似
#include<iostream>
using namespace std;
int main()
{
int a=10;
cout<<a++<<endl;//++在后,就是先用再加,即先输出在自加1
cout<<a++<<endl;
cout<<a<<endl;
return 0;
}
输出:
10
11
12
5.C++赋值运算符实例讲解
#include<iostream>
using namespace std;
int main()
{
int a=10;//定义变量a,并且将10作为初始化值赋给a
int b;
b=a;//将a的值赋值给b
return 0;
}
6.C++关系运算符实例讲解
7.C++逻辑运算符实例讲解
– 2.3 控制流程语句(条件语句、循环语句)
8.C++if选择结构实例讲解
9.C++中switch选择结构实例讲解
10.C++中while循环结构实例讲解
11.C++do while循环实例讲解
12.C++中的for循环实例讲解
3 函数和参数传递
1.C++中函数调用的用法
2.C++带默认形参值的函数
带有默认值的参数放在最右边
3.C++网数重载实例讲解
4.C++函数模板
格式
template <class T>
return_type function_name(T arg)
{
// 函数体
}
实例
template <class T>
T max(T a, T b)
{
return (a > b) ? a : b;
}
5.C++内联函数inline实例详解
在 C++ 中,inline
是一种关键字,用于告诉编译器将函数代码插入到每个调用该函数的地方,而不是像普通函数那样生成单独的函数调用。这样可以减少函数调用的开销,提高程序的执行效率。
内联函数的特点包括:
-
减少函数调用开销:内联函数的代码会直接插入到调用位置,避免了函数调用时的压栈、跳转等操作,从而提高程序的执行效率。
-
提高代码的可读性:内联函数适合用于定义简单、短小的函数,可以使代码更加简洁易懂。
-
然而,需要注意的是,内联函数适合用于定义简单的函数,对于复杂的函数或包含循环、递归等控制结构的函数,并不适合使用内联。此外,编译器并不一定会将所有的内联函数都真正进行内联展开,具体情况取决于编译器的实现和优化策略
3. 第三部分:数组和指针
– 3.1 数组的定义和使用
– 3.2 字符串处理
– 3.3 指针的基本概念和用法
– 3.4 动态内存分配
4 面向对象编程
– 4.1 类和对象的概念
1.C++类的定义
2.C++对象的建立和使用
– 4.2 成员函数和成员变量
– 4.3 继承和多态
1.C++继承和派生实例讲解
2.C++三种继承方式实例详解
3.C++派生类的构造函数实例详解
4.C++派生类的析构函数实例详解
在 C++ 中,对象的构造和析构顺序如下:
1. 当创建一个对象时,首先会调用该对象所属类的构造函数来初始化对象的成员变量。如果对象是派生类,还会依次调用基类的构造函数。
2. 构造函数按照继承关系从最底层的基类开始逐级向上调用,直到最终调用派生类的构造函数。
3. 在所有基类的构造函数被调用完毕后,派生类的构造函数体才会执行。
4. 对象的析构顺序与构造相反,即先调用派生类的析构函数,然后依次调用基类的析构函数,直到最终调用对象所属类的析构函数。
总结起来,构造顺序是由基类向派生类,析构顺序则是由派生类向基类。这种顺序确保了派生类在构造和析构过程中能够正确地初始化和清理其成员以及继承的基类成员。
在你的示例代码中,创建对象 A 和 B 时,先调用 `Student` 类的构造函数来初始化对象的成员变量,然后在程序结束时析构这两个对象,先调用 `Student` 类的析构函数来清理对象,这就是构造和析构的顺序。
5.C++虚基类及虚基类的定义使用
1.C++多态性实例讲解
2.C++虚函数实例详解
3.C++虚析构函数实例详解
4.C++纯虚网数与抽象类总结
– 4.4 构造函数和析构函数
`set` 函数的作用可以理解为“设置”或“设定”,其主要目的是用来修改对象的属性或状态。在面向对象编程中,对象通常具有一些属性(成员变量),我们可以通过`set`函数来修改这些属性的值,而不直接访问对象的私有成员变量。这样做的好处是可以对对象的属性进行封装,隐藏内部实现细节,提高代码的安全性和可维护性。`Set`函数被用来设置学生对象的学号、姓名和成绩,允许外部代码修改这些属性值。这样,当需要更新学生对象的信息时,可以通过调用`Set`函数来实现,而不需要直接操作学生对象的私有成员变量。这种封装的方式有助于保持代码的整洁性和可扩展性。
– 4.5 深拷贝与浅拷贝
在C++中,与类名同名,且形参是本类对象的引用类型的函数,叫做拷贝构造函数(Copy Constrctor),与构造函数一样,当我们不主动定义的时候,系统也会自动生成一个,进行两个对象成员之间对应的简单赋值,用来初始化一个对象。
深拷贝构造函数,不仅可以进行数据的拷贝,也可以为成员分配内存空间,实现真正的拷贝。
浅拷贝只复制对象本身,不会复制对象内部的引用类型数据,而深拷贝会复制对象及其所有引用类型数据,确保对象之间的独立性。在选择使用深拷贝还是浅拷贝时,需要根据具体情况和需求来决定。
– 4.6 this指针
在C++编程语言中,this指针是一个指向当前对象的指针。每个对象在创建时都会分配一块内存来存储其成员变量和成员函数,this指针指向这块内存的首地址。通过this指针,可以在成员函数中访问当前对象的成员变量和成员函数。
例如,在一个类中定义了成员变量a和成员函数func,可以使用this指针来访问当前对象的成员变量:
class MyClass {
public:
int a;
void func() {
this->a = 10;
}
};
在上述代码中,this->a表示访问当前对象的成员变量a,并将其赋值为10。
如果没有使用this指针,编译器会认为a是一个局部变量而无法正确赋值。
需要注意的是,this指针只能用于非静态成员函数中,并且不能被显式地修改。通常情况下,我们不需要显式地使用this指针,编译器会自动将成员函数中所有未指定对象的成员变量和成员函数解析为当前对象的成员变量和成员函数。但在某些情况下,如函数参数与成员变量同名时,使用this指针可以显式地指定访问的成员变量是当前对象的成员变量。
以下是一个使用this指针显式指定成员变量的例子:
#include <iostream>
using namespace std;
class MyClass {
public:
int num;
MyClass(int num) {
this->num = num; // 使用this指针显式指定访问成员变量
}
void printNum(int num) {
cout << "类中成员变量num的值为:" << this->num << endl; // 使用this指针显式指定访问成员变量
cout << "函数参数num的值为:" << num << endl;
}
};
int main() {
MyClass obj(10);
obj.printNum(20);
return 0;
}
在上述代码中,MyClass类中定义了一个成员变量num和一个构造函数,使用this指针来显式指定访问成员变量。同时类中还定义了一个成员函数printNum,其中也有一个参数名为num,如果不使用this指针,则无法区分成员变量和函数参数,使用this指针可以显式地指定访问成员变量。
当我们使用obj.printNum(20)调用成员函数时,输出结果为:
类中成员变量num的值为:10
函数参数num的值为:20
可以看到,使用this指针显式指定访问成员变量,可以避免成员变量和函数参数名称重复带来的歧义问题。
– 4.7 友元类和友元函数
友元函数是定义在类外部的普通函数,但是可以访问类的私有成员变量和保护成员变量。友元函数可以被声明在类的任何地方,包括public、protected和private部分,但是它不是类的成员函数,因此不能使用成员运算符”.”或”->”。
友元函数的作用是:在需要访问类的私有成员时,提供一种非成员函数的方式来访问这些成员,从而增加程序的灵活性和可维护性,并且可以减少代码的复杂度。
定义一个友元函数,需要在类的内部进行声明,使用关键字friend,示例如下:
class MyClass {
private:
int x;
public:
friend void friendFunc(MyClass obj); // 声明友元函数
};
void friendFunc(MyClass obj) {
cout << "访问MyClass中的私有成员x:" << obj.x << endl; // 可以访问MyClass中的私有成员x
}
int main() {
MyClass obj;
friendFunc(obj); // 调用友元函数
return 0;
}
在上述代码中,我们定义了一个名为MyClass的类,并声明了一个私有成员x。然后,在类中声明了一个友元函数friendFunc,可以访问MyClass类中的私有成员x。在main函数中,我们创建了一个MyClass对象obj,并调用friendFunc函数来访问类中的私有成员x。
需要注意的是,友元函数并不属于类的成员函数,因此在定义时不能使用类作为返回类型或者参数类型。友元函数的形参可以是类的对象,也可以是其他类型的数据。
5. 第五部分:高级特性
– 5.1 模板编程
– 5.2 异常处理
– 5.3 文件操作
1.C++读写文件操作
2.C++如何打开文件
3.C++读文件操作
4.C++写文件操作
5.C++如何关闭文件
– 5.4 标准库介绍(STL)
6. 第六部分:进阶主题
– 6.1 多线程编程
– 6.2 智能指针
– 6.3 Lambda 表达式
– 6.4 移动语义和右值引用
7. 第七部分:常用技巧和优化
– 7.1 常见问题和解决方案
– 7.2 代码优化技巧
– 7.3 调试技巧和工具
– 7.4 编程风格和规范