C++深入学习

文章目录

  • 一、C++关键字
    • 1.alignas
    • 2.alignof
    • 3.auto
    • 4.constexpr
    • 5.decltype取类型
    • 6.dynamic_cast
    • 7.enum
    • 8.namespace
    • 9.noexcept
    • 10.nullptr
  • 二、C++Class
    • 1.前置声明
    • 2.构造函数常用的表达方式
    • 3.类的原则
    • 4.多态
    • 5.循环的新形式
  • 三、C++智能指针
    • 1.shared_ptr(共享指针)
    • 2.weak_ptr
    • 3.在类中调用指向自己的智能指针
    • 4.unique_ptr<>
  • 四、Lamda函数
  • 五、函数模板特化

一、C++关键字

1.alignas

设置结构体至少按多少字节对齐

struct alignas(8) S{};

2.alignof

求出结构体中最大字节的变量

3.auto

自动判断变量的类型

auto a = 1.0  //此时的auto等效于float

4.constexpr

函修饰符,用了之后函数编译前就可以确定返回的值

constexpr int factorial(int a);
char group[factorial(6)];  //这样就不会报错

5.decltype取类型

//一般用法
print(decltype(int));
//常见用法
//根据a+b的类型确定返回值
template<typename T,typename U>
auto add(T a,U b)->decltype(a+b){
	return a+b;
}

6.dynamic_cast

用于做类型转换,主要是将指向子类的父类指针转换为子类指针

Derived *d = dynamic_cast<Derived *>(b1); //失败返回空指针

7.enum

枚举类型

enum Color{red,green,blue}; //默认从0开始赋初值
//如果两个enum有重复的要使用前缀
enum class Color1{red,green,blue}; 
enum class Color2{red,green,blue}; 
Color r = Color1::Blue;

8.namespace

用于声明命名空间,两个命名空间里可以声明相同的函数或变量

namespace XGroup{
	class A{
		int value;
	};
}
namespace YGroup{
	class A{
		int value;
	};
}
void testNamespace()
{
	XGroup::A a;
	YGroup::A b;
}

9.noexcept

告诉编译器修饰的函数不会抛异常

10.nullptr

专门的空指针关键字

二、C++Class

1.前置声明

如果一个类中调用了另一个类的指针,可以使用前置声明实现而不需要导入头文件,节省编译时间和内存空间

class RulOfFive;
class Test
{
private:
	RulOfFive *rule;
};

2.构造函数常用的表达方式

explicit 的作用是表明构造函数是显示的,是明确的,不存在隐式的转换

class Parent()
{
public:
	explicit Parent(const char* name):_name(name){}
private:
	const char* _name;
};
class Child()
{
public:
	explicit Child(const char* name,const char* school):Parent(name),_school(school){}
private:
	const char* _name;
	const char* _school;
};
}

3.类的原则

  • 定义需要管理的资源(动态分配内存),需要在析构函数中释放资源
  • 如果类支持拷贝,需要自己定义拷贝函数和拷贝操作符,不然系统会自动调用默认的拷贝函数进行浅拷贝,只是拷贝了类的成员函数,这样会导致析构的时候重复析构
    C++深入学习_第1张图片
  • 左值和右值
    左值为普通变量,右值为不能取地址的临时变量
    利用std::move()可以将一个左值当右值使用。
    常引用作为参数才可以传入右值,引用不能传入右值
  • 析构函数不要抛出异常,构造函数鼓励抛出异常

4.多态

构造函数从基类开始调用,析构函数从派生类开始调用
如果需要用指向派生类的基类指针做什么事情的话必须将基类的析构函数设置为virtual否则释放的时候只会调用基类的析构函数而不会调用派生类的析构函数

5.循环的新形式

//取值
for(auto v:group)
{
}
//取引用
for(auto &v:group)
{
}
//取常引用
for(const auto &v:group)
{
}

三、C++智能指针

1.shared_ptr(共享指针)

  • 本质上是利用了类的构造函数和析构函数
  • 通过引用实现共享,最后一个人使用完毕后释放
//创建智能指针
auto p = make_shared<int>(3);
//智能指针的拷贝
auto q = p;
cout << *p;
//显示多少人占有该智能指针,应该显示为2
cout<<p.use_count();
//获得智能指针管理的裸指针
int* lp = p.get();
//释放原有指针或重新设置指针
p.reset(6);  //设置新指针
p.reset();   //释放原有指针

2.weak_ptr

  • 主要是用来防止shared_ptr循环引用的·情况
  • 它指向的是一个shared_ptr管理的对象,只可以从一个shared_ptr或另一个weak
    _ptr对象构造

3.在类中调用指向自己的智能指针

  • 是不能利用this指针构造的,这样析构的时候this指针也被析构了
  • 解决办法:让该类继承一个模板类:enable_shared_from_this<>,然后调用其中的方法shared_from_this()就可以获得指向自己的shared_from智能指针。
  • 但是注意不能在构造函数和析构函数中使用。
  • 还要注意这样创建的类只能使用智能指针的方法创建和管理。

4.unique_ptr<>

  • 在某个特定的时刻,只有唯一引用维护一个裸指针。
  • 如果没有必要,一般都用unique_ptr而不是shared_ptr。
  • release()释放自己的引用,返回裸指针。
  • reset() 重新设置新指针或者释放原有指针
  • 如果一个函数接口需要传入uniqueobject的值而不是常引用,要将它转换为右值引用std::move(obj),然后传入函数后资源就到形参里面去了,函数调用完就释放了,而外面的指针就是空指针了

四、Lamda函数

在这里插入图片描述
在这里插入图片描述
里面是&代表外面的变量可以以引用的形式传入,=是以值传入

五、函数模板特化

  • 函数模板特化指函数模板在模板参数为特定类型下的特定实现
    C++深入学习_第2张图片

你可能感兴趣的:(linux服务器编程,c++,指针,内存管理,多态)