一、基础
1.1 简单示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class Solution { public: string longestCommonPrefix(vector<string>& strs) { if (!strs.size()) { return ""; } int length = strs[0].size(); int count = strs.size(); for (int i = 0; i < length; ++i) { char c = strs[0][i]; for (int j = 1; j < count; ++j) { if (i == strs[j].size() || strs[j][i] != c) { return strs[0].substr(0, i); } } } return strs[0]; } };
|
1.2 指针
1.2.1 原理
指针地址的原理如下:
1.2.2 指针与数组的关系
指针与一维数组的关系:
指针与二维数组的关系:
1.2.3 注意事项
- a与&a[0]等价
- a[0]与*a、&a[0][0]等价
- pa指向地址array[0][0]
- (pa+i)地址指向array[i][0]
- (*(pa+i)+j)地址指向array[i][j]
- 二维数组的一维访问形式a[i][j]=*(a[0]+n*i+j)=*(*a+n*i+j)
1.3 字符串
在C/C++中的字符串均以char[]类型进行存储,char是一个字符类型 C++的内置类型,C/C++中的string实为一个类
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| char a[10] = "123"; a[0] = 'a'; *(a+1) = 'b'; cout << *(a+1);
const char *str1 = "abcde"; str1 = "efghi"; cout << str1;
string a("abc"); printf("%s\n", a.c_str());
|
1.4 容器
1.4.1 容器分类
序列式容器:
- 序列式容器:每个元素都有固定位置--取决于插入时机和地点,和元素值无关
- Vector:将元素置于一个动态数组中加以管理,可以随机存取元素(用索引直接存取),数组尾部添加或移除元素非常快速。但是在中部或头部安插元素比较费时
- Deque:是“double-ended queue”的缩写,可以随机存取元素(用索引直接存取),数组头部和尾部添加或移除元素都非常快速。但是在中部或头部安插元素比较费时
- List:双向链表,不提供随机存取(按顺序走到需存取的元素,O(n)),在任何位置上执行插入或删除动作都非常迅速,内部只需调整一下指针
关联式容器:
- 关联式容器:元素位置取决于特定的排序准则,和插入顺序无关
- Set/Multiset:内部的元素依据其值自动排序,Set内的相同数值的元素只能出现一次,Multisets内可包含多个数值相同的元素,内部由二叉树实现,便于查找;
- Map/Multimap:Map的元素是成对的键值/实值,内部的元素依据其值自动排序,Map内的相同数值的元素只能出现一次,Multimaps内可包含多个数值相同的元素,内部由二叉树实现,便于查找
其他结构容器:
- priority_queue:维护一个堆结构
- stack:维护一个栈
1.5 函数
二、面向对象
2.1、面向对象的特性
2.1.1 封装
- 封装就是将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的函数代码进行有机的结合,形成“类”,其中的数据和函数都是类的成员
2.1.2 继承
- 根据现实中的事物之间的关系,抽象出了继承的概念
- C++语言中提供了类的继承机制,允许程序员在保持原有类特性的基础上,进行更具体、更详细的说明
2.1.3 多态
2.2、类
2.2.1 类的定义
1 2 3 4 5 6 7
| class Clock{ public: void setTime(int newH,int newM,int newS); void showTime(); private: int hour,minute,second; };
|
2.2.2 类的成员函数
1 2 3 4 5
| 类外实现 返回值类型 类名::函数成员名(参数表) { 函数体 }
|
2.2.3 类的访问控制权限
访问限制
访问权限 |
类内成员函数 |
类对象 |
友元函数 |
public |
YES |
YES |
YES |
protected |
YES |
NO |
YES |
private |
YES |
NO |
YES |
继承的权限变化
基类权限 |
public继承 |
protected继承 |
private继承 |
public |
public |
protected |
private |
protected |
protected |
protected |
private |
private |
不可访问 |
不可访问 |
不可访问 |
2.2.4 构造函数
- 构造函数的作用是在对象被创建时利用特定的值构造对象,将对象初始化为一个特定的状态
- 构造函数在对象被创建的时候被自动调用
- 构造函数的调用顺序:基类构造函数->对象成员构造函数->派生类本身的构造函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Clock{ public: Clock(){} Clock(int newH,int newM,int newS); void setTime(int newH,int newM,int newS); void showTime(); private: int hour,minute,second; };
Clock::Clock(int newH,int newM,int newS){ hour = newH; minute = newM; second = newS; }
|
2.2.5 拷贝构造函数
- 拷贝构造函数是一种特殊的构造函数,它在创建对象时,使用同一类中之前创建的对象来初始化新创建的对象,拷贝构造函数通常的步骤:
- 通过使用另一个同类型的对象来初始化新创建的对象。
- 复制对象把它作为参数传递给函数
- 复制对象,并从函数返回这个对象
语法
- 如果在类中没有定义拷贝构造函数,编译器会自行定义一个。如果类带有指针变量,并有动态内存分配,则它必须有一个拷贝构造函数。拷贝构造函数的最常见形式如下
- 在这里,obj 是一个对象引用,该对象是用于初始化另一个对象的
1 2 3
| classname (const classname &obj) { }
|
2.2.6 析构函数
- 析构函数用来完成对象被删除前的一些清理工作
- 析构函数是在对象的生产期即将结束的时刻被自动调用的
- 析构函数的调用顺序:派生类本身的析构函数->对象成员析构函数->基类析构函数(与构造顺序正好相反)
1 2 3 4 5 6 7 8 9
| class Clock{ public: Clock(); void setTime(int newH,int newM,int newS); void showTime(); ~Clock(){} private: int hour,minute,second; }
|
2.2.7 类的继承
语法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class 基类1{ }
class 基类2{ }
class 派生类:继承方式 基类1,继承方式 基类2{ 构造函数(参数列表){ 基类1构造函数(参数); 基类2构造函数(参数); 派生类 } }
|
实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| #include <iostream> using namespace std;
class Shape { public: void setWidth(int w) { width = w; } void setHeight(int h) { height = h; } protected: int width; int height; };
class PaintCost { public: int getCost(int area) { return area * 70; } };
class Rectangle: public Shape, public PaintCost { public: int getArea() { return (width * height); } }; int main(void) { Rectangle Rect; int area; Rect.setWidth(5); Rect.setHeight(7); area = Rect.getArea(); cout << "Total area: " << Rect.getArea() << endl; cout << "Total paint cost: $" << Rect.getCost(area) << endl; return 0; }
|