c++编程基础(零)—— 知识点小结

c++知识点小记

使用assign(仅顺序容器)

vector<char> c;     
vector<int> i;
i.assign(c.begin(),c.end());       //不同类型元素的替换

使用swap
使用swap元素不会真正移动。对于string会导致指针失效,对于array会真正交换元素;

使用insert

 

vector<int> i1{ 1,2,3,4,5 };
auto x = i1.begin() + 2;
i1.insert(x, { 111,222,333 });  //在x前插入

emplace操作
当调用push或insert时先构造一个临时对象再拷贝这个对象,而emplace直接在容器的内存空间内构造对象;


string的find方法与算法库的find函数
find方法未找到返回string::npos(-1);find函数返回一个迭代器,未找到则迭代器指向序列末尾;


bind参数绑定

 

auto g = bind(f,a,b,_2,c,_1); //f为接受五个参数的函数
g(x,y);//将参数a,b,c,绑定于g

反向迭代器

当我们从一个普通迭代器初始化为一个反向迭代器,或是给一个反向迭代器赋值时,结果迭代器与原迭代器指向的并不是相同的元素。反向迭代器使用base方法得到普通迭代器。

析构函数

析构函数会首先执行程序体然后按照成员初始化顺序的逆序销毁成员。

如果一个类需要自定义析构函数,几乎可以肯定他也需要自定义拷贝赋值运算符和拷贝构造函数。

=delete

class my{
    my() = default;   //使用默认的构造函数
    my(const my&) = delete;//阻止拷贝
}

可以对任何函数使用=delete,但不能创建析构函数delete的临时对象。

allocator类

allocator<double> allo;
auto const p =  allo.allocate(10);
allo.construct(p,10,10);

使用allocator类可以将内存分配与对象构造分离

右值引用与std::move与引用限定符

右值引用可以简单的理解为对没有名字的值的引用,std::move的作用是获得一个左值的右值引用;

引用限定符&、&&为指定函数引用为左值或右值引用; 

重载==与<操作符

如果存在唯一一种逻辑可靠的<定义,则应该为这个类定义<运算符。如果类同时还包含==,则当且仅当<的定义和==产生的结果一致时才定义<运算符。

initializer_list<T>

不确定个数形参函数可以使用如fun(initializer_list<string> str){}

调用如fun({"hello","world",...});

函数对象

重载了()操作符的类对象可以作为类似函数的方式使用;

sort(str.begin(),str,end(),greater<string>()); //在算法中使用标准库函数对象

虚函数与默认实参

使用virtual定义虚函数;

如果我们通过基类的引用或指针调用函数,则使用基类中定义的默认实参,即使实际运行的是派生类中的函数版本也是如此。

如果虚函数使用默认实参,则基类和派生类中定义的默认实参最好一致。

纯虚函数与抽象基类

可以将类的方法定义为fun( ) = 0;来作为一个纯虚函数,含有纯虚函数的类为抽象基类。抽象基类负责定义接口,我们不能直接创建一个抽象基类对象。

名字查找优先于类型检查

如果派生类的成员与基类的某个成员同名,则派生类将在其作用域类隐藏该基类成员,即使派生类成员和基类成员的形参列表不一致。所以想要覆盖基类虚函数,那么派生类中的虚函数必须与基类中的虚函数必须有相同的形参列表。

虚析构函数

如果我们删除的是一个指向派生类对象的基类指针,则需要虚析构函数;

virtual~base() = default;

虚继承

不论虚基类在继承体系中出现了多少次,在派生类中都只包含唯一一个共享的虚基类子对象。

//指定虚基类的方式是在派生列表中添加关键字virtual
class child :public virtual base{};

自定义类使用set

一般需要在自定义类里重载<操作符

bool operator<(const T&) const{
//满足相等返回false}

以下为c++知识点补充:

 左值引用(&):并非对象,只是将引用与它的初始值绑定在一起,且并不能更改绑定对象。

指针(*):指针是一个对象,拥有普通对象的性质。

nullptr:一种特殊类型的字面值,它可以被转换为任意其他的指针类型。

void*:一种特殊的指针类型,可用于存放任意对象的地址。

const:使用const对对象进行限定使之不能被改变。默认状态下const对象仅在文件内有效(想要在多个文件间共享const对象,必须在变量的定义之前添加extern关键字)。

常量指针(*const):允许把指针定义为常量(不变的是指针本身),且必须初始化。

顶层const:指针本身是个常量;底层const:指针所指对象是个常量。

常量表达式(constexpr):指不会改变并且在编译过程中就能得到计算结果的表达式 (设计目的为了效率,编译期能够确定就在编译期优化)。

别名声明:using A = B(typedef A B);

auto:类型推断一般会忽略掉顶层const

decltype:从表达式的类型推断出要定义的变量的类型,decltype(fun()) a;decltype((i))永远得到的都是一个引用。

标准库函数begin()、 end():使用数组作为他们的参数,返回指针。

static_cast:对任何具有明确定义的类型转换,只要不包含底层const都可以使用static_cast<T>.

const_cast:改变常量属性,常用于有函数重载的上下文中。

reinterpret_cast:强制转换。

尾置返回类型:auto func(int i)->int(*)[10];

可变数据成员:一个mutable修饰的成员永远不会是const即使它是const对象的成员。

友元类:每个类负责控制自己的友元类或友元函数。

构造函数在执行之前会完成成员变量的初始化,函数体内使用=就是赋值操作了。如果成员是const、引用,或者属于某种未提供默认构造函数的类类型,我们必须通过构造函数初始化列表(A(int i):a(i),b(i){})为这些成员提供初值。

explicit:抑制构造函数定义的隐式转换,explicit构造函数只能用于直接初始化。

聚合类可以使用 成员初始值列表{}进行初始化。

array<T,n>:具有固定大小,除了指定元素类型,还要指定容器大小

lambda捕获列表:[ ] 显式捕获、隐式捕获、引用捕获、值捕获方式

当我们需要为一个lambda定义返回类型时必须使用尾置返回类型 [](int i)->int{if(i<0) return -i;else return i;}

iostream迭代器:将输入输出流当做一个特定类型的元素序列来处理

使用make_shared<T>(\\输入T构造函数参数)来替代使用new创建动态内存

若使用智能指针指向的对象没有自己的析构函数,我们可以在智能指针创建时定义一个删除器。shared_ptr<T> p(&c,delet_T);delet_T()为我们自定义的删除器。

构造函数中,成员的初始化是在函数体执行之前完成;析构hans函数中,先执行函数体然后销毁成员。

若一个类需要析构函数则它肯定需要一个拷贝构造函数和一个拷贝赋值运算符。

大多数赋值运算符组合了析构函数和拷贝构造函数的工作。

类型转换运算符:operator type() const;

在模板参数列表中class与typename含义相同;

pair<_1,_2>有默认的比较函数:先会比较_1的大小,若相同再比较_2的大小;

final关键字:防止继承的发生

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值