C++
面向对象
后缀 .cpp 编译: g++ xxx.cpp
**封装:**封装的抽象过程,描述一类事物的特点
**类:**一类事物的统称
**对象:**某类事物的一个特别/个体
如何描述一类事物:数据成员,成员方法。
实例化对象:int i;
例: A a1; “实例化一个A类型的对象a1”
继承:核心,在原有的特点/功能上加上新特点/功能。
多态:延申, 同一条命令作用在不同对象上显示效果不同。
1.cin (输入) – 默认与键盘链接,接受从键盘输入的数据信息。
语法:cin >> 变量 ;
2.cout(输出) – 默认与屏幕链接,将数据显示到屏幕上。
语法: cout << 变量 ;
如果没指定名空间:using namespace std;
域解析运算符
#include <iostream> using namespace std; int main() { int i; char str[32]; cout << "Hello World!" << endl; cin >> i; cout << "i = " << i << " &i = " << &i << endl; //C++能自动识别变量类型 cin >> str; cout << "str = " << str << endl; return 0; }
注意:C++在创建变量时,必须给变量一个初始值,否则会报错
封装的意义:
语法: class 类名{ 访问权限: 属性 / 行为 };
class Clock { public: void ShowTime(); void SetTime(int h,int m,int s); private: int hour; int minute; int second; };
访问权限有三种: 公共权限 public ==类内可以访问 类外可以访问== 保护权限 protected ==类内可以访问 类外不可以访问== 私有权限 private ==类内可以访问 类外不可以访问==
示例:
#include <iostream> me/xiaolei/teacher/example/c++/hello.cpp' ' using namespace std; //内联函数inline 1类内实现 2用inline关键字类内声明,实现可以写在类外 //public protected private class Clock { public: void ShowTime(); void SetTime(int h,int m,int s); private: int hour; int minute; int second; }; void Clock::ShowTime() { cout << hour << ":" << minute << ":" << second << endl; } void Clock::SetTime(int h,int m,int s) { hour = h; minute = m; second = s; } int main() { Clock c1; c1.ShowTime(); return 0; }
inline 内联函数 带参宏 ,建议性机制
宏占用的是编译时间,不占用运行时间
对一个类进行计算大小,只能计算数据类型的大小,函数不计入空间大小
对象的初始化和清理也是两个非常重要的安全问题
一个对象或者变量没有初始状态,对其使用后果是未知
同样的使用完一个对象或变量,没有及时清理,也会造成一定的安全问题
构造函数作用:初始化,在一个对象生成的时候被隐式调用
默认有一个系统生成的构造函数,若果我们自行实现了构造函数,系统默认的那个不再生成
长相:函数与类同名,不需要返回值,可传参(1或多),可无参
构造函数语法:类名(){}
代码演示:
#include <iostream> using namespace std; /*类中的特殊函数*/ /* 构造函数:作用:初始化,在一个对象生成的时候被隐式调用 默认有一个系统生成的构造函数,若我们自行实现了构造函数,系统默认的那个不再生成 长相:函数名与类同名,不需要返回值,可传参(可1个或多个)可无参 构造函数可以同时存在多个 */ class Clock { public: Clock(); //构造函数可以存在多个 Clock(int h); void ShowTime(); void SetTime(int h,int m,int s); private: int hour; int minute; int second; }; Clock::Clock() { cout << "Clock()" << endl; hour = minute = second = 0; } Clock::Clock(int h) { cout << "Clock(int)" << endl; hour = h ; minute = second = 0; } void Clock::ShowTime() { cout << hour << ":" << minute << ":" << second << endl; } void Clock::SetTime(int h,int m,int s) { hour = h; minute = m; second = s; } int main() { Clock c0; Clock c1(4); Clock c2(14,15); // c1.ShowTime(); return 0; }
类外不能复制
#include <iostream> using namespace std; /*类中的特殊函数*/ /* 构造函数:作用:初始化,在一个对象生成的时候被隐式调用 默认有一个系统生成的构造函数,若我们自行实现了构造函数,系统默认的那个不再生成 长相:函数名与类同名,不需要返回值,可传参(可1个或多个)可无参 构造函数可以同时存在多个 */ class Clock { public: Clock(int h=0,int m=0,int s=0); void ShowTime(); void SetTime(int h,int m,int s); private: int hour; int minute; int second; }; Clock::Clock(int h,int m,int s) { cout << "Clock(3*int)" << endl; hour = h ; minute = m; second = s; } void Clock::ShowTime() { cout << hour << ":" << minute << ":" << second << endl; } void Clock::SetTime(int h,int m,int s) { hour = h; minute = m; second = s; } int main() { Clock c0; Clock c1(4); Clock c2(14,15); // c1.ShowTime(); return 0; }
析构函数作用:清理或销毁,在一个对象生命周期即将终止时被隐式调用
默认有一个系统生成的析构函数,若果我们自行实现了构造函数,系统默认的那个不再生成
长相:函数与类同名,前面加~,不需要返回值
析构函数语法: ~类名(){}
给变量加个大括号相当于一个临时变量
代码演示:
#include <iostream> using namespace std; /*类中的特殊函数*/ /* 析构函数:作用:清理或销毁,在一个对象生命周期即将终止时被隐式调用 默认有一个系统生成的析构函数,若我们自行实现析构函数,系统默认的那个不再生成 长相:函数名与类同名,前面加~,不需要返回值,不可传参 */ class Clock { public: Clock(int h=0,int m=0,int s=0); ~Clock(); void ShowTime(); void SetTime(int h,int m,int s); private: int hour; int minute; int second; }; Clock::Clock(int h,int m,int s) { cout << "Clock(3*int)" << endl; hour = h ; minute = m; second = s; } Clock::~Clock() { cout << "~Clock() " << hour << endl; } void Clock::ShowTime() { cout << hour << ":" << minute << ":" << second << endl; } void Clock::SetTime(int h,int m,int s) { hour = h; minute = m; second = s; } int main() { Clock c0; { Clock c2(14,15); } Clock c1(4); return 0; }
拷贝构造函数作用:初始化,在一个对象生成的时候,且用相同类型的已存在的对象初始化时调用拷贝构造
默认有一个系统生成的拷贝构造函数,若果我们自行实现了拷贝构造函数,系统默认的那个不再生成
长相:函数与类同名,不需要返回值,可传参(参数为常量的引用)。
代码演示:常量的引用
”同一块存储的空间有相同的名字“
#include <iostream> using namespace std; /*类中的特殊函数*/ /* 拷贝构造函数:作用:初始化 ,在一个对象生成时,且用相同类型的已存在的对象初始化时调用拷贝构造 默认有一个系统生成的拷贝构造函数,若我们自行实现了拷贝构造函数,系统默认的那个不再生成 长相:函数名与类同名,无返回值,参数为常引用 */ class Clock { public: Clock(int h=0,int m=0,int s=0); Clock(const Clock &other); ~Clock(); void ShowTime(); void SetTime(int h,int m,int s); private: int hour; int minute; int second; }; Clock::Clock(int h,int m,int s) { cout << "Clock(3*int)" << endl; hour = h ; minute = m; second = s; } Clock::Clock(const Clock &other) { cout << "Clock(&)" << endl; hour = other.hour; minute = other.minute; second = other.second; } Clock::~Clock() { cout << "~Clock() " << hour << endl; } void Clock::ShowTime() { cout << hour << ":" << minute << ":" << second << endl; } void Clock::SetTime(int h,int m,int s) { hour = h; minute = m; second = s; } int main() { Clock c1(4); Clock c2 = c1; c2.ShowTime(); return 0; }
C++程序在执行时,将内存大方向划分为4个区域
C++中利用new操作符在堆区开辟数据
堆区开辟的数据,由程序员手动开辟,手动释放,释放利用操作符 delete
语法:new 数据类型
利用new创建的数据,会返回该数据对应的类型的指针
示例1: 基本语法
#include <iostream> using namespace std; int main() { char *p = new char; if(p == NULL) return -1; *p = 'a'; cout << *p << endl; delete p; //利用delete释放堆区数据 return 0; }
示例2:开辟数组
#include <iostream> using namespace std; /* new delete */ class Clock { public: Clock(int h=0,int m=0,int s=0); Clock(const Clock &other); ~Clock(); void ShowTime(); void SetTime(int h,int m,int s); private: int hour; int minute; int second; }; Clock::Clock(int h,int m,int s) { cout << "Clock(3*int)" << endl; hour = h ; minute = m; second = s; } Clock::Clock(const Clock &other) { cout << "Clock(&)" << endl; hour = other.hour; minute = other.minute; second = other.second; } Clock::~Clock() { cout << "~Clock() " << hour << endl; } void Clock::ShowTime() { cout << hour << ":" << minute << ":" << second << endl; } void Clock::SetTime(int h,int m,int s) { hour = h; minute = m; second = s; } //堆区开辟数组 int main() { //执行new时,一定会经历构造的过程 Clock *p = new Clock[5]; //连续的需要五个这个类型的空间 delete []p; return 0; }
示例3:
#include <iostream> using namespace std; class A { public: A() { str = new char[1]; *str = '\0' }; ~A() { delete []str; } void Show() { cout << str << endl; } private: char *str; }; int main() { A a1; return 0; }
继承是面向对象三大特性之一
有些类与类之间存在特殊的关系,例如下图中:
我们发现,定义这些类时,下级别的成员除了拥有上一级的共性,还有自己的特性。
这个时候我们就可以考虑利用继承的技术,减少重复代码
继承方式一共有三种:
父类-子类 基类-派生类 parent->: public protected private public: public protected - protected: protected protected - private: private private -
示例:
#include <iostream> using namespace std; class A { public: A() {cout << "A()" << endl;} ~A() {cout << "~A()" << endl;} void GetA() { cout << "A::GetA() " << a << endl;} protected: void Show() { cout << "A::Show()" << a << endl;} private: int a; }; class B : public A { public: B() {cout << "B()" << endl;} ~B() {cout << "~B()" << endl;} void GetShow() { Show(); } void GetA() { cout << "B::GetA() " << endl;} }; int main() { B tmp; tmp.GetA(); return 0; }