# C++基础
## 友元函数 友元类
~~~
权访问类的所有私有(private)成员和保护(protected)成员
class Box
{
double width;
public:
double length;
friend void printWidth( Box box );
void setWidth( double wid );
};
friend class ClassTwo;
~~~
## 类
~~~cpp
//public 类外部可以访问
//protected 子类可以访问,外部不能访问
//private 只能本类访问
//delete 删除该类型函数,程序中不可调用,调用会报错
//defaulte 指定默认构造函数
//explicite 防止类构造函数的隐式自动转换
//final 终结虚函数传递, 子类不能再实现该函数 只能用于虚函数
//override 说明该函数式覆盖函数,父类必须有其相同定义, 只能用于虚函数
class FirstClass {
public:
virtual int getLength( void );
FirstClass (bool ) = delete;
FirstClass (char ) = default;
explicite FirstClass ( int len ); // 简单的构造函数
FirstClass ( const Line &obj); // 拷贝构造函数
~FirstClass (); // 析构函数
virtual void vir_fun(); //虚函数 类多态使用
virtual int area() = 0; //不用给出实现 派生类必须实现
protected:
private:
}
//继承
//public 保持之类的访问属性 即: public protected private
//protected 改变继承的 public访问控制位 protected,其他不变
//private 改变继承的 protected public为 private
//子类只能访问父类 protected public的成员不能访问 private的成员
class ChildClass : public FirstClass{
using FirstClass::FirstClass;
final void vir_fun() {}
final int area() {}
virtual int getLength()override {}
}
//多态
FirstClass *firstClass = (new ChildClass(5));
firstClass->vir_fun() //执行ChildClass类的函数
~~~
## 重载操作符
~~~
可以被重载的操作符:new,new[],delete,delete[],+,-,*,/,%,^,&,|,~,!,=,<,>,+=,<<,>>,<<=,>>=,++,!=,<=,>=,&&,||,++,--,->*,->,(),[]
不可以被重载的操作符:. .* :: ?:
class UPInt { // "unlimited precision int"
public:
UPInt& operator++(); // ++ 前缀
const UPInt operator++(int); // ++ 后缀
UPInt& operator--(); // -- 前缀
const UPInt operator--(int); // -- 后缀
UPInt& operator+=(int); // += 操作符,UPInts
// 与ints 相运算
...
};
~~~
##
## 强类型枚举 enum class
~~~
enum class Direction {
Left, Right
};
enum class Answer {
Right, Wrong
};
enum class Answer : unsigned long {
}
auto a = Direction::Left;
auto b = Answer::Right;
if (a == b)
std::cout << "a == b" << std::endl;
else
std::cout << "a != b" << std::endl;
~~~
## 静态断言 static assert
~~~
static_assert( size_of(int) == 4 );
~~~
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)
## 构造函数的相互调用 delegating constructor
~~~
class A {
public:
A(int x, int y, const std::string& name) : x(x), y(y), name(name) {
if (x < 0 || y < 0)
throw std::runtime_error("invalid coordination");
if (name.empty())
throw std::runtime_error("empty name");
}
A(int x, int y) : A(x, y, "A")
{}
A() : A(0, 0)
{}
private:
int x;
int y;
std::string name;
};
~~~
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)
## constexpr常量表达式
~~~
constexpr 用于向编译器指出,常量表达式
constexpr int a = 20; /* 20 是常量表达式 */
constexpr int b = a + 2; /* a + 2 是常量表达式 */
~~~
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)
## \*\*override 和 final \*\*虚函数
~~~
override 修饰函数, 函数必须覆盖父类的函数,
final 打断virtual的传播 如果一个虚函数被final修饰所有的子类都不能覆盖该函数,
~~~
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)
## 默认构造函数 default
~~~
class A {
public:
A(int i) {}
A() = default;
};
~~~
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)
## 删除构造函数 delete
~~~
class A {
public:
A() = delete;
};
~~~
## lambad
~~~
Lambda 表达式: Lambda表达式就是匿名函数,。
[capture](parameter)mutable -> return-type{state}
capture 是捕捉列表。
parameter 是参数列表,就是函数的那些传入变量。
mutable 这个后面再介绍。
return-type 返回值的类型,如果返回值明确,也可以省略。
state 是函数体
Lambad 表达式引入符:
[] 不捕获任何局部变量
[=] 以传值的方式捕获外部变量
[&] 以引用的方式捕获外部变量
[x, &y] x传值捕获, y引用捕获
[=, &x] x引用捕获, 其他传值捕获
[&, x] x传值捕获, 其它引用捕获
[a, &str]->QString{} 传值捕获a, 引用捕获str, 返回值是QString。
~~~
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)
##
## 智能指针
~~~
//std::auto_ptr 指针对象析构 指向对象自动释放
auto item = auto_ptr<Item> (new Item());
auto_ptr复制构造函数中把真是引用的内存指针进行的转移 可能产生野指针
//std::shared_ptr
shared_ptr自动销毁所管理的对象
std::shared_ptr 是一种智能指针,它能够记录多少个 shared_ptr 共同指向一个对象,从而消除显示的调用 delete,当引用计数变为零的时候就会将对象自动删除。
std::shared_ptr 可以通过 get() 方法来获取原始指针,通过 reset() 来减少一个引用计数,并通过get_count()来查看一个对象的引用计数。
shared_ptr<int> p1;
//被初始化成为一个空指针
shared_ptr<int> p2 (new int(4));
//指向一个值是4的int类型数据
shared_ptr<int> p3 = new int(4);
//错误,必须直接初始化
shared_ptr<T> p;
//空智能指针,可指向类型是T的对象
if(p)
//如果p指向一个对象,则是true
(*p)
//解引用获取指针所指向的对象
p -> number == (*p).number;
p.get();
//返回p中保存的指针
swap(p,q);
//交换p q指针
p.swap(q);
//交换p,q指针
make_shared<T>(args)
//返回一个shared_ptr的对象,指向一个动态类型分配为T的对象,用args初始化这个T对象
shared_ptr<T> p(q)
//p 是q的拷贝,q的计数器++,这个的使用前提是q的类型能够转化成是T*
shared_pts<T> p(q,d)
//p是q的拷贝,p将用可调用对象d代替delete
//上面这个我其实没懂,也没有查出来这个的意思
p =q;
//p的引用计数-1,q的+1,p为零释放所管理的内存
p.unique();
//判断引用计数是否是1,是,返回true
p.use_count();
//返回和p共享对象的智能指针数量
p.reset();
p.reset(q);
p.reset(q,d);
//reset()重新设置 新的指想对象
//std::weak_ptr
weak_ptr是一种不控制所指向对象生存期的智能指针,指向shared_ptr管理的对象,但是不影响shared_ptr的引用计数。它像shared_ptr的助手,一旦最后一个shared_ptr被销毁,对象就被释放,weak_ptr不影响这个过程。
weak_ptr是为配合shared_ptr而引入的一种智能指针来协助shared_ptr工作,它可以从一个shared_ptr或另一个weak_ptr对象构造,它的构造和析构不会引起引用计数的增加或减少。没有重载 * 和 -> 但我们可以通过lock来获得一个shared_ptr对象来对资源进行使用,如果引用的资源已经释放,lock()函数将返回一个存储空指针的shared_ptr。 expired函数用来判断资源是否失效。
weak_ptr的使用更为复杂一点,它可以指向shared_ptr指针指向的对象内存,却并不拥有该内存,而使用weak_ptr成员lock,则可返回其指向内存的一个share_ptr对象,且在所指对象内存已经无效时,返回指针空值nullptr。
注意:weak_ptr并不拥有资源的所有权,所以不能直接使用资源。
可以从一个weak_ptr构造一个shared_ptr以取得共享资源的所有权。
weak_ptr<T> w(sp);
//定义一个和shared_ptr sp指向相同对象的weak_ptr w,T必须能转化成sp指向的类型
w = p;
//p是shared_ptr或者weak_ptr,w和p共享对象
w.reset();
//w置为空
w.use_count();
//计算与w共享对象的shared_ptr个数
w.expired();
//w.use_count()为0,返回true
w.lock();
//w.expired()为true,返回空shared_ptr,否则返回w指向对象的shared_ptr
share_ptr<X> pnew(w.lock())
//std::unique_ptr
unique_ptr 不共享它的指针。它无法复制到其他 unique_ptr,无法通过值传递到函数,也无法用于需要副本的任何标准模板库 (STL) 算法。只能移动unique_ptr。
可以使用 移动语义转移所有权
unique_ptr<int> pInt(new int(5));
unique_ptr<int> pInt2 = std::move(pInt); // 转移所有权 转换为右值
函数可以返回 unique_ptr 类似移动语义 函数返回值是右值
unique_ptr<int> clone(int p)
{
unique_ptr<int> pInt(new int(p));
return pInt; // 返回unique_ptr
}
int main() {
int p = 5;
unique_ptr<int> ret = clone(p);
cout << *ret << endl;
}
//示例代码
#include <memory>
#include <iostream>
#include <utility>
class Foo{
public:
Foo() = default;
Foo(int a):_a(a) {}
~Foo() {}
int get_a(){
return _a;
}
void set_a(int a) {
_a = a;
}
private:
int _a;
};
std::unique_ptr<Foo> change_a(std::unique_ptr<Foo> f)
{
f->set_a(10);
return f;
}
int main()
{
// std::make_unique是c++14才有
std::unique_ptr<Foo> pf = std::make_unique<Foo>(10);
// unique_ptr的复制构造函数和拷贝构造函数是删除了的,这样保证了对象独占,如果不是独占,那么跟shared_ptr
// 就是一样的功能了。
// std::unique_ptr<Foo> pf1 = pf; // compile error
// 按值传参,会有拷贝问题,同上
// auto p = change_a(pf); //compile error
auto p = change_a(std::move(pf));
std::cout << "get_a = " << p->get_a() << std::endl;
if(!pf)
{
std::cout << "pf is nullptr" << std::endl;
}
//owner transfer from function
std::unique_ptr<Foo> pf2 = std::make_unique<Foo>(11);
std::unique_ptr<Foo> p2 = change_a(std::move(pf2));
std::cout << "get_a = " << p2->get_a() << std::endl;
if(!pf2)
{
std::cout << "pf2 is nullptr" << std::endl;
}
//使用reset
pf2.reset(new Foo(12));
std::cout << "pf2 is not null: " << pf2->get_a() << std::endl;
//release获取原始指针
Foo* ff = pf2.release();
if(!pf2)
{
std::cout << "pf2 is nullptr" << std::endl;
}
std::cout << "ff is not null: " << ff->get_a() << std::endl;
return 0;
}
~~~
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)
## 智能指针数组删除
~~~
//! shared_ptr
std::shared_ptr<int> p(new int[10],std::default_delete<int[]>());
//! unique_ptr
std::unique_ptr<int[]> p(new int[10]);//ok
auto value = make_unique<int[]>(5);
auto value = shared_ptr<Employee[]>(new Employee[5]); c++ 17开始
auto value = shared_ptr<Employee[]>(new Employee[5]{0, 1, 2, 3, 4});
~~~
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)
##
##
##
![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)
- c++基础
- 官方在线文档
- auto typename decltype类型推导
- c++常用关键字
- 取消变量未使用警告
- 变量类型
- 字面量
- 指针和引用
- 统一初始化 结构化绑定
- foreach遍历
- using使用
- alignas alignof
- 模板
- 引用和完美转发
- 逗号表达式
- 异常 try catch
- string和string_view
- c++程序退出
- 函数参数类型和个数
- lambda
- 单例模式
- c++标准库
- 文档库
- cmath 算数库
- utilities
- array 数组
- vector 动态数组
- 变量类型推断function
- 正则表达式
- 随机数
- 多线程并发
- cout输出格式化
- 常用std函数
- hash定制
- c++使用第三方库实列
- google glog日志库
- gtest单元测试
- 线程池
- c++ rpc
- Mongoose网络协议
- cpp-httplib
- json ⚡ - JSON for Modern C++
- JeayeSON c++14
- ini文件解析库
- libuv uvw
- boost
- https://www.boost.org/doc/libs/1_79_0/
- ptree ini json xml
- dll
- lockfree
- socket
- cpp serial
- c++常用库列表
- c++常用调试技巧
- 死锁
- valgrind使用
- gdb
- core 生成
- c++编程总览