Note
2020/06
C++
- 类
class Box
{
public: //类成员的访问属性
double length; // 盒子的长度
double breadth; // 盒子的宽度
double height; // 盒子的高度
};
构造函数/析构函数
- 对象
Box Box1; // 声明 Box1,类型为 Box
Box Box2; // 声明 Box2,类型为 Box
- 继承
class derived-class: access-specifier base-class
使用private继承,父类的protected和public属性在子类中变为private;
使用protected继承,父类的protected和public属性在子类中变为protected;
使用public继承,父类中的protected和public属性不发生改变
- 多继承
class <派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>,…
{
<派生类类体>
};
- 重载
class printData //函数重载
{
public:
void print(int i) {
cout << "整数为: " << i << endl;
}
void print(double f) {
cout << "浮点数为: " << f << endl;
}
void print(char c[]) {
cout << "字符串为: " << c << endl;
}
};
class Box //运算符重载
{
public:
double getVolume(void)
{
return length * breadth * height;
}
void setLength( double len )
{
length = len;
}
void setBreadth( double bre )
{
breadth = bre;
}
void setHeight( double hei )
{
height = hei;
}
// 重载 + 运算符,用于把两个 Box 对象相加
Box operator+(const Box& b)
{
Box box;
box.length = this->length + b.length;
box.breadth = this->breadth + b.breadth;
box.height = this->height + b.height;
return box;
}
private:
double length; // 长度
double breadth; // 宽度
double height; // 高度
};
-
多态
-
虚函数
虚函数 是在基类中使用关键字 virtual 声明的函数。在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数。
我们想要的是在程序中任意点可以根据所调用的对象类型来选择调用的函数,这种操作被称为动态链接,或后期绑定。
-
纯虚函数 规范派生类的定义
-
-
数据抽象和数据封装 :抽象是将类的实现和接口分离,封装是将数据和操作捆绑隐藏
-
多线程
HANDLE WINAPI CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes, //线程安全相关的属性,常置为NULL
SIZE_T dwStackSize, //新线程的初始化栈在大小,可设置为0
LPTHREAD_START_ROUTINE lpStartAddress, //被线程执行的回调函数,也称为线程函数
LPVOID lpParameter, //传入线程函数的参数,不需传递参数时为NULL
DWORD dwCreationFlags, //控制线程创建的标志
LPDWORD lpThreadId //传出参数,用于获得线程ID,如果为NULL则不返回线程ID
);
Mutex :创建同步互斥量
- 同步异步(消息通信机制)与阻塞非阻塞(程序在等待调用结果(消息,返回值)时的状态.)
调用者主动等待这个调用的结果。
*调用*在发出之后,这个调用就直接返回了,所以没有返回结果。
阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。
非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。
Qt
-
与MFC比较:
- 跨平台
- 底层细节封装的较好
- QML 界面设计比较容易?
-
IDE选择Qt Creator 5.9.1,安装过程注意选上MinGW
-
时间问题对于具体的组件和目录结构先不做具体分析。。。
-
.pro:项目管理文件用于记录项目的一些设置,以及项目包含文件的组织管理。一般不需要太过注意
-
.ui :可视化设计的界面
-
信号与槽(Siginal & Slot)
信号(Signal)就是在特定情况下被发射的事件,例如PushButton 最常见的信号就是鼠标单击时发射的 clicked() 信号,一个 ComboBox 最常见的信号是选择的列表项变化时发射的 CurrentIndexChanged() 信号。
槽(Slot)就是对信号响应的函数。槽就是一个函数,与一般的C++函数是一样的,可以定义在类的任何部分(public、private 或 protected),可以具有任何参数,也可以被直接调用。槽函数与一般的函数不同的是:槽函数可以与一个信号关联,当信号被发射时,关联的槽函数被自动执行。
-
一个信号可以关联多个槽函数,多个信号也可以关联同一个槽
- 严格的情况下,信号与槽的参数个数和类型需要一致,至少信号的参数不能少于槽的参数。如果不匹配,会出现编译错误或运行错误。
-
在使用信号与槽的类中,必须在类的定义中加入宏 Q_OBJECT。
-
-
Qt纯代码设计:感觉不清真,都有QML的可视化设计界面和封装好的功能,从头开始设计的话纯代码感觉更加复杂
STL(Standard Template Library,标准模板库)
STL的代码从广义上讲分为三类:algorithm(算法)、container(容器)和iterator(迭代器)
algorithm
- 算法部分主要由头文件
, 和 组成。
- sort(first_pointer,first_pointer+n,cmp)
- 时间复杂度类快排,n*log2(n),一直认为sort只是标准库实现的快速排序,然而STL中的sort并非只是普通的快速排序,除了对普通的快速排序进行优化,它还结合了插入排序和堆排序,STL中引入了SORT_MAX变量来作为数据量大小的判断标准。根据不同的数量级别以及不同情况,能自动选用合适的排序方法。当数据量较大时采用快速排序,分段递归。一旦分段后的数据量小于某个阀值,为避免递归调用带来过大的额外负荷,便会改用插入排序。而如果递归层次过深,有出现最坏情况的倾向,还会改用堆排序
- 由于cmp参数的存在,我们可以通过自定义比较函数实现自定义排序的对象和排序的标准,方便我们对各种数据类型进行排序。
Container
- STL容器就为我们提供了这样的方便,它允许我们重复利用已有的实现构造自己的特定类型下的数据结构,通过设置一些模版类,STL容器对最常用的数据结构提供了支持,容器部分主要由头文件
, - ,
, ,
-
vector
-
基本定义
template<class _Ty, class _Ax> class vector : public _Vector_val<_Ty, _Ax> { // varying size array of values public: /********/ protected: pointer _Myfirst; // pointer to beginning of array pointer _Mylast; // pointer to current end of sequence pointer _Myend; // pointer to end of array };
-
头文件
#inlcude <vector>
-
一些接口
void push_back(const _Ty& _Val) //插入元素 { // insert element at end if (size() < capacity()) _Mylast = _Ufill(_Mylast, 1, _Val); else insert(end(), _Val); //空间不足时,就会触发内存的二次分配 } void pop_back() //删除元素 { // erase element at end if (!empty()) { // erase last element _Destroy(_Mylast - 1, _Mylast); --_Mylast; } } void reserve(size_type _Count)//设置容器容量 { // determine new minimum length of allocated storage if (capacity() < _Count) { // not enough room, reallocate pointer _Ptr = this->_Alval.allocate(_Count); _Umove(begin(), end(), _Ptr); size_type _Size = size(); if (_Myfirst != 0) { // destroy and deallocate old array _Destroy(_Myfirst, _Mylast); this->_Alval.deallocate(_Myfirst, _Myend - _Myfirst); } _Myend = _Ptr + _Count; _Mylast = _Ptr + _Size; _Myfirst = _Ptr; } } void resize(size_type _Newsize, _Ty _Val)//改变容器size { // determine new length, padding with _Val elements as needed if (size() < _Newsize) _Insert_n(end(), _Newsize - size(), _Val); else if (_Newsize < size()) erase(begin() + _Newsize, end()); } iterator erase(const_iterator _First_arg, const_iterator _Last_arg) //将后面的有效元素向前拷贝,并将后面无效元素的空间析构,更新_Mylast变量 { // erase [_First, _Last) iterator _First = _Make_iter(_First_arg); iterator _Last = _Make_iter(_Last_arg); if (_First != _Last) { // worth doing, copy down over hole pointer _Ptr = _STDEXT unchecked_copy(_VEC_ITER_BASE(_Last), _Mylast, _VEC_ITER_BASE(_First)); _Destroy(_Ptr, _Mylast); _Mylast = _Ptr; } return (_First); } void _Assign_n(size_type _Count, const _Ty& _Val)//assign 擦除n个已有的元素,并插入Count个Val元素 { // assign _Count * _Val _Ty _Tmp = _Val; // in case _Val is in sequence erase(begin(), end()); insert(begin(), _Count, _Tmp); }
-
-
list
-
基本定义
template<typename T> struct __list_node{ typedef __list_node* list_node_pointer; list_node_pointer prev; list_node_pointer next; T data; };
-