C++类知识点
Visual Studio的使用
1. 右键速览定义
2. visual studio 项目架构
参考
- 解决方案 - 一个个project - cpp/ .h
如上图,一个解决方案下有一个sln文件及其包含的两个项目的文件夹。而每一个项目除了其所包含的.cpp .h源码文件外,其余的就两个projcetName.vcxproj是上面提到的project文件;另一个就是projectName.vcxproj.filters 文件,这个文件保存了在项目中的源代码文件文件的分组情况,例如常见的头文件,源文件,也可以添加自定义的分组,这些信息就保存在该文件中。有了这些了解以后,将项目托管到git上,就知道了那些文件应该push,那些文件应该ignore了。
3. 注释
ctrl+c 添加注释
ctrl+u 去除注释
注意,如果把整行选中,出来的注释是 // 形式的
如果选中的行前面有空格,那么注释是 /* */形式的
C++(面向对象)三大特性
封装、继承、多态
封装
封装可以隐藏实现细节,使得代码模块化
封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。
数据抽象(abstraction)
只向外界提供关键信息,并隐藏其后台的实现细节,即只表现必要的信息而不呈现细节。
抽象类(abstract class)
类中至少有一个函数被声明为纯虚函数/纯虚函数是通过在声明中使用=0来指定。
抽象类不能被实例化。
多态
多态指的是父类类型的指针指向其子类对象,可以调用子类中被重写(override)的方法
C++中,实现多态有以下方法:虚函数,抽象类(纯虚函数,即 virtual 函数名()=0),重写(override),模板(重载和多态无关)。
重载(overload)与重写(override)的区别
成员函数被重载的特征:
(1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4)virtual 关键字可有可无。
重写是指派生类函数覆盖基类函数,特征是:
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有virtual 关键字。
例子:(通过虚函数实现多态)
class A
{
public:
A(){}
virtual void foo()
{
cout<<"This is A."<<endl;
}
};
class B: public A
{
public:
B(){}
void foo()
{
cout<<"This is B."<<endl;
}
};
int main(int argc, char *argv[])
{
A *a = new B();
a->foo();
if(a != NULL)
delete a;
return 0;
}
继承
通过继承机制,可以利用已有的数据类型来定义新的数据类型。所定义的新的数据类型不仅拥有新定义的成员,而且还同时拥有旧的成员。我们称已存在的用来派生新类的类为基类,又称为父类。由已存在的类派生出的新类称为派生类,又称为子类。
公有继承、私有继承、保护继承
private:可以被自己访问,但是不能被子类访问
protected:可以被自己和自己的子类访问,但是自己不能访问其他实例化对象的 protected
public:都可以访问
动态联编、静态联编
动态联编: 在运行的时候,自动判断指向的成员函数
静态联编:在编译阶段,确定指向的成员函数是指针类型的成员函数
虚函数
虚函数的定义要遵循以下重要规则:
1.如果虚函数在基类与派生类中出现,仅仅是名字相同,而形式参数不同,或者是返回类型不同,那么即使加上了virtual关键字,也是不会进行滞后联编的。
2.只有类的成员函数才能说明为虚函数,因为虚函数仅适合用于有继承关系的类对象,所以普通函数不能说明为虚函数。
3.静态成员函数不能是虚函数,因为静态成员函数的特点是不受限制于某个对象。
4.内联(inline)函数不能是虚函数,因为内联函数不能在运行中动态确定位置。即使虚函数在类的内部定义定义,但是在编译的时候系统仍然将它看做是非内联的。
5.构造函数不能是虚函数,因为构造的时候,对象还是一片未定型的空间,只有构造完成后,对象才是具体类的实例。
6.析构函数可以是虚函数,而且通常声名为虚函数。
static类数据成员/成员函数
两者都不能用this指针指向他们
- 类数据成员
static类数据成员独立于一切类对象存在。
static不会像普通类数据成员一样每一个类对象都有一份,全部类对象是共享一个static类成员的。
static类对象必须要在类外进行初始化
class Text{
public:
static int count;
} ;
int Text::count=0; //必须初始化
- 类成员函数
类成员函数里不能访问非static类成员
虚函数表vtable以及vptr
如果一个类包含了虚函数,那么在创建对象时会额外增加一张表,表中的每一项都是虚函数的入口地址,虚函数按照创建的优先顺序排列。这张表就是虚函数表,也称为 vtable。
可以认为虚函数表是一个数组。 为了把对象和虚函数表关联起来,编译器会在对象中安插一个指针vptr(在对象对应的内存空间的开头),指向虚函数表的起始位置。
例子:
class A{
protected:
int a1;
int a2;
public:
virtual void display(){
cout<<"A::display()"<<endl;
}
virtual void clone(){
cout<<"A::clone()"<<endl;
};
};
class B: public A{
protected:
int b;
public:
virtual void display(){
cout<<"B::display()"<<endl;
}
virtual void init(){
cout<<"B::init()"<<endl;
}
};
class C: public B{
protected:
int c;
public:
virtual void display(){
cout<<"C::display()"<<endl;
}
virtual void execute(){
cout<<"C::execute()"<<endl;
}
};
各个类的内存分布如下所示:
Operator
- c++ 中的operator()有两大主要作用:
Overloading------重载()操作符;
Casting------实现对象类型转化。
STL
queue
queue的实现:底层使用链表(linked list)实现
vector
原理:内部使用array实现,所以要更改大小为taks linear time
- 头文件
#include<vector>
- vector的初始化
vector<vector<int>> v(n, vector<int>(n, 0))
优先队列
在<queue>
中,有priority_queue
priority_queue<int, vector,greater> big;
big.top() 访问的是最小元素
big.pop() 弹出来的耶是最小的元素
优先队列就是根据一定的顺序对进入队列的数进行排序,是用堆实现的。
C++ 零散知识点
1. 浮点数精度
float的十进制的精度为为6~7位
double精度最高位16位,一定可以保证15位
2. namespace
namespace参考
3. _declspec(dllexport)与_declspec(dllimport)
_declspec(dllexport)与_declspec(dllimport)是相互呼应,只有在DLL内部用dllexport作了声明,才能在外部函数中用dllimport导入相关代码
4. 运算符重载
classA& operator=(...){
}
5. math.h
pow
fabs
6. 智能指针
自己管理内存,不用 delete了
c++智能指针详解
智能指针原理:引入控制块,对引用计数
shared_ptr
unique_ptr:仅有一个指针指向一块内存区域
weak_ptr:辅助shared_ptr
7. 头文件
包含所有头文件的头文件
#include<bits/stdc++.h>
8. delete 和 delete[]
如果数据类型有析构函数,则需要使用delete []。
单单使用delete 则只调用了数组里面第一个元素的构造函数。
或者说
new -> delete
new [] -> delte[]
内联函数
利:避免了指令的来回跳转,加快程序执行速度
弊:代码被多次复制,增加了代码量,占用更多的内存空间
头文件
cstdio
cstdio是 c++版本的c语言的<stdio.h>,里面的函数如 scanf, print, fopen等
注意 scanf一个字符(%c)时,前面不能有空格,不然要先在前面加一个%c,以达到吸收空格的目的
字符串操作
坑
- to_string(char)是错误的,因为char底层是int,所以to_string后会转换成ASCII码
substr
string.substr(start_pos, length)
比如:
s.substr(i, j-i+1); // 取[i,j]里的字符串
string和int相互转换
C++ 11的新特性
-
auto
-
列表初始化
-
decltype:求表达式的类型
-
nullptr
-
右值引用,move(把左值转换成右值)
-
Lambda表达式
-
智能指针
-
正则表达式
-
在STL里增加了无序容器
-
for循环访问容器里的元素