-
01.C++概述
C++是一种通用编程语言,它在C语言的基础上进行了扩展和改进。以下是C++的一些主要特性和概述:
1.面向对象编程(OOP)支持:
类和对象: C++引入了类和对象的概念,使得编程更加模块化和可维护。类是一种用户定义的数据类型,而对象是该类型的实例。
封装: C++通过将数据和函数操作封装在类中,实现了数据隐藏和抽象。这样,只有类的成员函数能够访问类的私有成员。
继承: 允许一个类继承另一个类的特性,通过这种方式可以实现代码重用和扩展。
多态: C++支持运行时多态性,通过虚函数和函数重载来实现。这使得程序能够在运行时选择调用不同的函数。
2泛型编程支持:
模板: C++引入了模板,允许编写通用的函数和类,这样可以在不同数据类型上进行操作。模板提供了泛型编程的能力,增加了代码的灵活性和复用性。
STL(标准模板库): STL是C++标准库的一部分,其中包含了多个通用的数据结构和算法模板,如向量、链表、队列、排序算法等。STL使得编写高效和可复用的代码更为容易。
3其他特性:
函数重载和操作符重载: 允许在同一作用域中定义多个具有相同名称但参数列表不同的函数,以及对操作符进行重载,使其能够在不同的上下文中执行不同的操作。
异常处理: C++支持异常处理机制,使程序可以在运行时检测和响应错误,提高程序的可靠性和稳定性。
动态内存分配: 提供new和delete运算符,允许程序在运行时动态分配和释放内存。
多线程支持: C++11及以后的标准引入了对多线程编程的支持,包括原子操作、线程、互斥锁等。C++是一种功能丰富、灵活且高性能的编程语言,它继承了C语言的特性,并引入了许多新的概念和功能,使得开发者能够更有效地进行面向对象和泛型编程。
02.第一个程序helloworld
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;//标准命名空间
int main()
{
//cout是标准的输出流对象,打印字符串,
//endl是刷新缓冲区,并换行
cout << "hello world!" << endl;
system("pause");
return EXIT_SUCCESS;
}
写一个 "Hello, World!" 程序,实际上在创建一个基本的C++程序框架。这是一个非常简单的例子,但它包含了一些基本的C++编程概:
1.预处理器指令:
#define _CRT_SECURE_NO_WARNINGS
这是一个预处理器指令,它告诉编译器忽略与安全性相关的警告。这主要是因为在一些编译器中,使用一些不安全的函数(如 gets、scanf)会导致警告,而这个指令可以禁止这些警告。在VS2019和VS2022中你会发现一些奇怪的警告导致编译不通过,加上这句头你会发现警告消失了。
2.包含头文件:
#include<iostream>
这行代码包含了 <iostream> 头文件,该头文件提供了输入和输出的基本功能,包括 cout 和 endl。
3.命名空间:
using namespace std;
这行代码使用了命名空间 std,它包含了C++标准库的大部分组件。这样你就可以直接使用 cout 而不需要写 std::cout。
4.主函数:
int main()
{
//cout是标准的输出流对象,打印字符串,
//endl是刷新缓冲区,并换行
cout << "hello world!" << endl;
system("pause");
return EXIT_SUCCESS;
}
5.int main() 是程序的主函数入口。
6.cout 是标准输出流对象,用于向控制台输出。
7."hello world!" 是要输出的字符串。
8.<< 是输出运算符,将字符串输出到 cout 流中。
9.endl 是 C++ 中的换行符,并且它会刷新输出缓冲区,确保字符串被立即输出到屏幕。
10.system("pause") 用于在程序执行完毕前暂停控制台的显示,等待用户按下任意键继续。
11.return EXIT_SUCCESS; 表示程序正常结束,并返回一个表示成功的状态码。 EXIT_SUCCESS 是C++标准库定义的一个常量,通常值为0。
12.注释:
//cout是标准的输出流对象,打印字符串,
//endl是刷新缓冲区,并换行
这是注释,用于解释代码的作用。在C++中,注释可以用 // 表示单行注释,也可以使用 /* ... */ 表示多行注释。
这个 "Hello, World!" 程序是一个简单的起点,后面会学习更多的基础语法知识。
03.面向对象的三大特征
封装,继承,多态
面向对象编程(OOP)的三大特征是封装、继承和多态。让我们对它们进行更详细的拓展:
1.封装(Encapsulation):
封装是指将数据和操作数据的方法绑定在一起的编程语言特性。
在面向对象的程序设计中,封装通过将数据(通常是成员变量)和操作数据的方法(通常是成员函数)封装在一个单独的单位中(即类)来实现。
封装的主要目的是隐藏实现细节,并限制对数据的直接访问,使得代码更加模块化、可维护和安全。
在C++中,封装可以通过访问控制符(如 public、private、protected)来实现,以控制成员的访问权限。
2.继承(Inheritance):
继承是指一个新类(子类/派生类)可以继承另一个已有类(父类/基类)的属性和行为的能力。
通过继承,子类可以重用父类的代码,并在此基础上添加新的属性和行为,从而提高代码的复用性和扩展性。
继承可以建立类之间的层次关系,形成类的继承树。
在C++中,继承分为公有继承、私有继承和保护继承,分别决定了派生类对基类成员的访问权限。
3.多态(Polymorphism):
多态是指一个对象可以在不同的情况下以不同的方式呈现出不同的行为或表现形态的能力。
多态分为编译时多态(静态多态)和运行时多态(动态多态)两种形式。
编译时多态是指在编译时确定调用的函数或方法,主要通过函数重载和操作符重载来实现。
运行时多态是指在运行时确定调用的函数或方法,主要通过虚函数和函数重写来实现。
多态提高了代码的灵活性和可扩展性,使得代码能够更容易地适应不同的需求和变化。
这三大特征是面向对象编程的核心概念,它们共同构建了面向对象的程序设计范式,并为程序的设计、开发和维护提供了强大的支持。通过充分理解和应用封装、继承和多态,可以编写出更加灵活、可扩展和易于维护的代码。
04.命名空间
1. 为什么有命名空间,是因为解决多人合作时取标识符是重命名的问题:
命名空间的引入是为了解决在大型项目或多人协作的软件开发中可能发生的命名冲突问题。当不同的开发者在项目中负责不同的模块或功能时,他们可能会使用相同的名称来表示不同的实体(变量、函数、类等)。命名空间允许开发者在全局范围内创建一个独特的命名空间,以将相关的标识符组织在一起,从而减少命名冲突的可能性。
2. 什么是命名空间:
命名空间是C++中一种用来避免命名冲突的机制,它允许程序员在代码中创建一个逻辑上独立的命名空间,将一组相关的标识符(变量、函数、类等)封装在这个命名空间中。命名空间通过关键字 namespace 定义,其目的是为了提供一种更加模块化和结构化的代码组织方式。
// 命名空间
namespace A {
int a;
void func() {
// ...
}
}
3. 命名空间的注意:
注意1:命名空间只能写在全局。
注意2:命名空间可以嵌套命名空间。
namespace Maker {
int a;
namespace B {
int b;
}
}
注意3:命名空间是开放,随时可以加入新成员,但是新成员只能在加入后使用。
namespace Maker {
int a;
namespace B {
int b;
}
}
namespace Maker {
int c; // 可以加入新成员
}
注意4:匿名命名空间,类似于 static int d = 50;。
namespace {
int d = 50;
}
注意5:命名空间可以取别名。
void test01() {
// 新名字 旧名字
namespace nameMaker = Maker;
cout << nameMaker::a << endl;
}
注意6:分文件编写代码时,如果 .h 中有两个命名空间,但是里面的成员函数或成员变量同名时,在 .cpp 中实现函数时,需要加上命名空间。
作用域运算符:
作用域运算符 :: 用来访问某个作用域里面的成员。在命名空间的情况下,它被用来指定某个命名空间中的成员。
// 示例
namespace MyNamespace {
int myVariable;
void myFunction() {
// ...
}
}int main() {
MyNamespace::myVariable = 42; // 使用作用域运算符访问命名空间中的变量
MyNamespace::myFunction(); // 使用作用域运算符访问命名空间中的函数
return 0;
}通过命名空间和作用域运算符的结合使用,可以更好地组织和管理代码,避免命名冲突,并提高代码的可读性和可维护性。
05. Using声明和编译指令
Using声明
using 声明用于在当前作用域中引入命名空间中的某个标识符,使其可以直接使用,而不需要在代码中完全限定命名空间。
namespace A {
int a = 10;
int b = 20;
int c = 30;
}void test01() {
// 使用using声明,使命名空间中的标识符可以直接使用
using A::a;
cout << a << endl;// 注意:在这个作用域内不能定义同名的变量
// int a = 50;
}Using编译指令
using 编译指令用于让某个命名空间中的所有标识符都可以直接使用,而不需要使用 namespace:: 进行限定。
namespace A {
int a = 10;
int b = 20;
int c = 30;
}void test02() {
// 使用using编译指令,让命名空间中的标识符都可以直接使用
using namespace A;
cout << a << endl;
cout << b << endl;
cout << c << endl;int a = 100; // 不会冲突,类似于命名空间中的a是全局变量,这里的a是局部变量
cout << "a=" << a << endl;
}06. Struct类型加强
加强一:定义变量时不需要使用struct
在C++中,可以直接使用结构体的名称来定义变量,无需再写 struct。
struct Point {
int x;
int y;
};void test() {
Point p1;
p1.x = 10;
p1.y = 20;
}加强二:结构体内可以写函数
在C++中,结构体内可以包含成员函数。
struct Rectangle {
int length;
int width;// 成员函数
int calculateArea() {
return length * width;
}
};void test() {
Rectangle r;
r.length = 5;
r.width = 10;int area = r.calculateArea();
cout << "Area: " << area << endl;
}
07. 更严格的类型转换
在C++中,更加强调类型安全,不允许隐式的类型转换,必须显式地进行类型转换。
08. 三目运算符
在C++中,三目运算符返回的是左值,而在C语言中返回的是右值。
09. C/C++的const
1. C语言的const
1.C语言中,const 修饰的变量都有空间。
2.const 修饰的全局变量具有外部链接属性。
2.C++语言的const
1.C++语言中,const 修饰的变量有时有空间,有时没有空间(发生常量折叠,且没有对变量进行取址操作)。
onst int aa = 10; // 没有内存
2.C++语言中const修饰的全局变量
3.具有内部链接属性:extern const int c = 300;(加上 extern 就变为外部链接属性)。
3. C++编译器不能优化的情况
1.不能优化自定义数据类型。
2.如果用变量给 const 修饰的局部变量赋值,编译器就不能优化。
3.尽量用const替代define
4.const 有数据类型,可以进行数据类型检查。
5.const 有作用域,define 不重视作用域,不能限定常量的使用范围。
10. 引用
1.引用的作用:
1.引用类似于C语言的指针,提供了对变量的别名访问。
2.使语法更加简洁,避免了使用指针的繁琐语法。
2.引用的定义:
引用就是给变量或对象空间取别名。
3.引用的语法:
void func(int &a) {
a = 200;
}void test02() {
int a = 10;
func(a);
cout << "a=" << a << endl;
}
4.引用的注意事项:
1.int &b = a; 中的 & 不是取地址操作符,而是引用的标记。
2.引用创建时必须初始化,如 int &pRef; 是错误的。
3.引用一旦初始化后,不能改变其指向。
4.引用必须引用一块合法的内存空间。
5.数组的引用:
int main() {
int arr[] = {1, 2, 3, 4, 5};// 第一种方法
typedef int(MY_ARR)[5];
MY_ARR &arref = arr;// 第二种方法
int(&arref2)[5] = arr;// 第三种方法
typedef int(&MY_ARR3)[5];
MY_ARR3 arref3 = arr;// Access elements using references
for (int i = 0; i < 5; i++) {
cout << arref[i] << endl;
}// Modify elements using references
for (int i = 0; i < 5; i++) {
arref2[i] = 100 + i;
cout << arref2[i] << endl;
}return EXIT_SUCCESS;
}
6.引用的本质:
1.引用的本质是编译器在内部使用常指针来实现。
2.例如,int& aRef = a; 在内部转换为 int* const aRef = &a;。
7. 指针的引用
.给指针变量这块空间取别名。
.示例代码:
void test01() {
char* p = "翠花";
char* &p1 = p;
cout << p1 << endl;
}
void func(char* &tmp) {
char *p;
p = (char*)malloc(64);
memset(p, 0, 64);
strcpy(p, "小花");
tmp = p;
}
void test02() {
char* mp = NULL;
func(mp);
cout << mp << endl;
}
05. C和C++的区别(了解)
1.结构体和函数:
C语言的结构体不能包含函数,而C++可以在结构体中定义函数。
2.结构体定义变量:
在C++中,不需要使用struct关键字就可以定义结构体变量。
3.类型检查:
C++有更严格的类型检查,提供更强大的类型安全性。
4.const修饰的变量:
在C++中,const修饰的变量有时不占用内存,而在C语言中都会分配内存。
5.三目运算符的返回值:
.C和C++中三目运算符返回值的类型可能不同。
5.引用和指针:
C++中的引用和C语言的指针功能类似,但语法更为简洁。