
C++基础
本专栏已完结,主要参考:
1、C++ Primer
2、C++标准库
3、C++template
4、www.cplusplus.com
5、https://zh.cppreference.com/w/cpp
Master Cui
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
C++知识点62——模板实参推断与函数模板的特化
一、函数指针与模板实参推断可以用函数模板初始化一个函数指针或给一个函数指针赋值示例template <typename T>int comp(const T &a, const T &b){ return 0;}int main(int argc, char const *argv[]){ int (*pf)(const int &, const int &)=comp;}上述代码通过函数指针的形参类型指定了函数模板的模板参数T原创 2020-12-27 19:04:43 · 364 阅读 · 1 评论 -
C++知识点61——typename与class、模板编程与继承、模板类和友元、类模板与static成员
一、typename与class的异同1、啥时候既可以使用typename,又可以使用class?当表示模板参数的时候,二者没有区别2、啥时候只能使用typename,不能使用class?当模板内部的成员表示一个类型时,必须使用typename,而不能使用class虽然书上是这样写的,但是实际并不使这样,在g++ 7.5.0测试发现,即使表示一个模板参数的类型成员,typename和class也没有明显差异示例1template <class T>class.原创 2020-12-27 19:00:30 · 2256 阅读 · 0 评论 -
C++知识点60——非类型模板参数
模板参数不仅可以使类型,也可以是值。可以用特定的类型名(比如int)而非typename或者class表示非类型模板参数。当模板被实例化时,非类型模板参数会被一个值而不是类型替代。非类型模板参数一、类模板的非类型模板参数仍然拿mystack举例,需要加一个int类型的模板参数,表示栈中能容纳元素的最大数目template <typename T, int maxcount, typename CONT = deque<T>>class mystack{pub.原创 2020-12-27 18:55:48 · 1190 阅读 · 0 评论 -
C++知识点59——类模板(4、类模板的模板参数是一个类模板)
接上一篇文章https://blog.csdn.net/Master_Cui/article/details/111824152七、类模板的模板参数是一个模板类类模板的模板参数本身可以是一个类模板,函数模板的模板参数不能是模板依然用mystack作为示例,新的mystack的定义如下template <typename T, int maxcount, template <typename ELE, typename alloc=allocator<ELE>原创 2020-12-27 18:50:27 · 734 阅读 · 1 评论 -
C++知识点58——类模板(3、类模板的成员模板)
接上一篇文章https://blog.csdn.net/Master_Cui/article/details/111824108六、类模板中的成员模板类的成员函数也可以被写成模板,因为模板的实例化需要在编译期确定,所以,成员模板不能是虚函数仍然拿mystack举例int main(int argc, char const *argv[]){ mystack<int, 10> si10; mystack<double, 20> sd20; si10=sd20;原创 2020-12-27 18:46:41 · 539 阅读 · 0 评论 -
C++知识点57——类模板(2、类模板的局部特化与默认模板实参)
接上一篇文章https://blog.csdn.net/Master_Cui/article/details/111824064四、类模板的局部特化类模板可以被局部特化(只指定部分模板参数而不指定所有模板参数)。因为局部特化仍然保留着未指定的模板参数,所以,局部特化的类模板仍然是个类模板,而不是类模板的实例此外,只能对类模板进行局部特化,不能对函数模板进行局部特化示例template <typename T1, typename T2>class test{publi原创 2020-12-27 18:42:35 · 350 阅读 · 0 评论 -
C++知识点56——类模板(1、模板类的介绍)
一、类模板和函数模板一样,类模板也得通过template关键字来声明和定义,C++标准库中有很多容器都是类模板示例template <typename T>class mystack{public: mystack(); mystack(const mystack<T> &rval); mystack<T> &operator=(const mystack<T> &rval); ~mystack(); vo原创 2020-12-27 18:39:03 · 387 阅读 · 0 评论 -
C++知识点55——函数模板
一、为啥需要模板防止相同功能的重复实现二、函数模板1、模板函数的定义template <typename T>const T& Max(const T &a, const T &b){ return a>b?a:b;}上述代码就是个最简单的函数模板template关键字表示模板,<>中的typename用来表示模板参数,模板参数名字是T。函数体中指向operator>,所以T必须支持operator>.原创 2020-12-06 18:09:01 · 379 阅读 · 0 评论 -
C++知识点54——RTTI(运行时类型识别)
一、RTTI概述RTTI的功能由两个运算符实现,一个是typeid,用来返回表达式的类型;另一个是dynamic_cast,作用是将基类的指针或引用安全地转为子类的指针或引用二、typeidtypeid的表达式形式是typeid(e),e可以是任意表达式或者类型,typeid的结果是个const对象的引用,该对象的类型是标准库type_info或type_info的子类,type_info类中有个name成员函数,返回值是个表示类型名字的字符串,所以typeid的结果可通过name方法查看.原创 2020-12-03 10:16:44 · 1182 阅读 · 0 评论 -
C++知识点杂记3——局部类、位域、volatile、链接指示、枚举、定位new
一、局部类局部类就是定义在函数内部的类,因为作用域只是在函数内部,所以,所有成员定义必须完整,在Qt的源码中有几处使用了局部类,见博客https://blog.csdn.net/Master_Cui/article/details/109162220因为局部类必须定义完整,所以不能在局部类中声明static成员变量,如果定义了static成员变量,要把static成员变量的定义放在类的外部,与局部类必须完整相违背二、位域位域就是含有一定数量二进制位的变量,变量的类型通常应该是无符号.原创 2020-12-01 11:18:16 · 276 阅读 · 0 评论 -
C++知识点杂记2——类成员指针、嵌套类和union
一、类成员指针1.概念类成员指针指向的是类的非static成员,因为类的static成员是所有类对象共有,所以static成员的指针和普通指针没有区别2.成员变量指针示例class test{public: test(){} ~test(){} int pub;private: int pri;};int main(int argc, char const *argv[]){ int test::*pi=&test::pub; test t.原创 2020-11-30 15:47:21 · 775 阅读 · 0 评论 -
C++知识点杂记1——typedef、static_cast、const_cast、遍历二维数组、聚合类
1.typedeftypedef一般是对某种类型的类型别名(不是变量别名)#include "head.h"typedef double db;int main(int argc, char const *argv[]){ mixtypename(); return 0;}void mixtypename(){ db d=1.2; cout<<d<<endl;}db就是double的别名,一般情况下,使用typedef一般可以认为是类型别名原创 2020-05-27 22:16:10 · 383 阅读 · 0 评论 -
C++知识点53——虚继承
二、虚继承1.概念默认情况下,C++的派生列表中不允许同一个基类出现两次,但是,如果两个基类都继承了同一个类A,那么两个基类派生出的子类就会包含两次类A的部分为了解决上述问题,C++中就出现了虚继承,通过虚继承,无论虚基类在整个继承链中出现了多少次,子类中都只出现一次。示例class animal{public: animal(){cout<<__func__<<endl;} ~animal(){cout<<__func__<<e原创 2020-11-25 21:25:56 · 559 阅读 · 0 评论 -
C++知识点52——多重继承
一、概念C++允许一个类拥有多个基类,所以就有了多重继承。多重继承和单一继承很多方面都是类似的。示例class zooanimal{public: zooanimal(){cout<<__func__<<endl;} virtual ~zooanimal(){cout<<__func__<<endl;}};class bear:public zooanimal{public: bear(){cout<<__func原创 2020-11-25 10:43:47 · 653 阅读 · 0 评论 -
C++知识点51——虚函数与纯虚函数(下)
接上一篇文章https://blog.csdn.net/Master_Cui/article/details/10995714610.练习示例class base{public: base(){cout<<__func__<<endl;} ~base(){cout<<__func__<<endl;} virtual void vfunc() {cout<<__func__<<"in base2"<<e原创 2020-11-22 16:49:58 · 427 阅读 · 0 评论 -
C++知识点50——虚函数与纯虚函数(上)
一、虚函数1.如果一个基类希望基类中的某些成员函数在子类中实现子类的自定义版本,就可以将该成员函数定义为virtual。2.当使用基类的指针或引用调用一个虚函数时,将会发生动态绑定(在运行时根据指针或引用的动态类型来决定调用对应动态类型中的虚函数),动态绑定发生时,编译器无法在编译时确定要调用哪个版本的虚函数。如果使用对象来调用成员函数,那么在编译期就能确定要调用的成员函数,因为此时类的静态类型和动态类型是一致的3.智能指针也支持虚机制所以,虚函数的实现基础:一是要有类的继承,二是基类指针或原创 2020-11-22 16:44:06 · 409 阅读 · 1 评论 -
C++知识点49——类继承与类的构造、拷贝、operator=和析构函数
一、类继承与构造函数在C++中,无论类是否有继承关系,每个类各自控制它自己的成员的初始化。子类虽然含有基类的成员,但是并不能对基类的成员直接初始化,需要使用基类的构造函数初始化子类中的基类部分。从语法上说,可以在子类的构造函数的函数体中给基类的protected或public成员赋值,但是最好不要这样做子类初始化时,会先调用基类的构造函数,初始化基类的部分并,然后按照子类成员在类中的声明顺序逐个初始化子类部分示例class base{public: base(): bpub(0原创 2020-11-21 15:25:16 · 996 阅读 · 0 评论 -
C++知识点48——类继承与类的作用域
一、静态类型决定了可访问的成员基类的对象、指针和引用的静态类型决定了可以访问哪些成员,即使通过基类的指针或者引用指向一个子类对象,也不能通过基类的指针或引用访问子类对象的成员示例class base{public: base(){cout<<__func__<<endl;} ~base(){cout<<__func__<<endl;} void funcb() {cout<<__func__<<endl;}};原创 2020-11-20 14:51:19 · 362 阅读 · 0 评论 -
C++知识点47——类继承中的类型转换与访问权限控制(下)
接上一篇文章https://blog.csdn.net/Master_Cui/article/details/109768311五、派生类向基类转换的可访问性当一个子类向基类转化时:有以下三条规则:1、只有子类public继承基类时,用户代码(比如main函数)才能将子类转为基类,如果是protected或者private继承,则用户代码无法完成转化示例class base{public: base(){cout<<__func__<<endl;}原创 2020-11-19 15:57:45 · 372 阅读 · 0 评论 -
C++知识点46——类继承中的类型转换与访问权限控制(中)
接上一篇文章https://blog.csdn.net/Master_Cui/article/details/109741735四、public继承、protected继承和private继承子类对继承的成员的访问权限受两个因素影响,第一个是继承成员在基类中的访问权限说明符,第二个是派生列表中的访问权限说明符。派生列表的访问说明符的作用是:使用子类时,控制子类中的基类成员的访问权限。也就是说,如果是public继承,基类中的成员在子类中的访问权限不变(无法将protected和pri原创 2020-11-18 11:18:23 · 312 阅读 · 0 评论 -
C++知识点45——类继承中的类型转换与访问权限控制(上)
一、类的继承与类型转换1.概述一般情况,如果想把一个类的指针或引用绑定到另外一个对象上,需要指针或者引用的类型与指向对象一致。但是存在继承关系的类是个例外:可以将基类的指针或者引用指向子类原因是因为:子类包含了父类非static成员和它本身的非static成员。因此,当一个基类的指针或引用指向子类对象时,所指向的真实对象有可能仅仅是父类,也有可能是完整的子类上图中,指针或引用的类型叫静态类型,指针或引用指向的对象叫动态类型。静态类型在编译期就已经确定,而动态类型是不确定的(有可能是父类对原创 2020-11-17 14:20:53 · 404 阅读 · 0 评论 -
C++知识点44——类的继承概述
类的继承,是新类从已有类那里得到已有的特性,或从已有类产生新类的过程。原有类称为基类或父类,新类称为派生类或子类。子类通过类派生列表确定子类继承了哪些类。类派生列表的形式如下class 子类名:访问说明符 基类1名, 访问说明符 基类2名, 访问说明符, 基类3名 { //...}示例class base1{public: base1(){} ~base1(){} };class base2{public: base2(){} ~base2(){}原创 2020-11-16 12:27:18 · 643 阅读 · 0 评论 -
C++知识点43——解引用运算符和箭头运算符的重载及智能指针类的实现
一、概念、在自定义行为类似指针的类时,需要重载*和->。C++中的智能指针就重载了这两个运算符。->必须是成员函数,*也应该是成员函数。与内置类型保持一致,这两个函数通常都是const的。以为*和->通常不会也不应该改变对象的状态*运算符的返回值无硬性规则,但是通常都是一个类型的引用->运算符的返回值必须是一个类的指针(或者重载了operator->的类的对象)。因为->的作用就是通过对象的指针获取对象的成员二、示例通过实现一个智能指针来熟悉这两.原创 2020-11-07 15:43:14 · 1321 阅读 · 0 评论 -
C++知识点42——下标运算符[]的重载及string类的实现
一、下标运算符的重载1.概念如果一个类表示容器,那么要重载下标运算符[],下标运算符必须是成员函数。下表访问运算符通常要有一个const版本和一个非const版本。如果不定义const版本,那么const对象将无法调用下表运算符。非const版本返回对应位置的引用,const版本返回常量对象的引用2.示例通过实现一个string类来熟悉下标运算符的重载string类的整体结构如下#include <utility>#include <iostream>.原创 2020-11-06 15:23:46 · 1944 阅读 · 0 评论 -
C++知识点41——运算符的重载概念与分数类实现(下)
接上篇文章https://blog.csdn.net/Master_Cui/article/details/109515571继续实现分数类和相关运算符的重载6.自增自减运算符(++ --)的重载因为内置类型的++ --分为前置类型和后置类型,所以,重载++和--时,也要区分前置和后置类型,而且,因为++和--会更改对象的状态,所以,应该把++和--定义为成员函数为了和内置类型的++和--保持一致,前置++ --运算符应该返回对象类型的引用(直接得到++ --运算符后的对象),而后置++ --类原创 2020-11-06 15:18:55 · 367 阅读 · 0 评论 -
C++知识点40——运算符的重载概念与分数类实现(中)
接上篇文章https://blog.csdn.net/Master_Cui/article/details/109515376,继续实现分数类和相关运算符的重载3.重载算术运算符和复合赋值运算符算术运算符应该定义为非成员运算符,主要是为了允许左侧或者右侧的运算对象能够转换成自定义类的类型(比如string中的operator+),因为算符运算符不会改变运算对象的状态,所以形参是const的引用。算术运算符得到的新值不同于运算对象,经常是局部变量,所以返回值是一个局部变量的拷贝如果一个类定义了原创 2020-11-05 16:54:49 · 401 阅读 · 0 评论 -
C++知识点39——运算符的重载概念与分数类实现(上)
一、概念在博客https://blog.csdn.net/Master_Cui/article/details/109461561已经提到了赋值运算符的重载,重载运算符是有特殊名字的函数:名字由operator后接运算符组成。可以有返回值和形参。除了重载函数调用运算符operator()外,其他重载运算符函数不能有默认实参。重载运算符函数是用来完成自定义类的运算符操作,不能重载内置类型的运算符,不能新发明运算符进行重载。已有的运算符中,大部分能重载,小部分不能重载,如下图在上述能重载的运算符原创 2020-11-05 16:49:45 · 561 阅读 · 0 评论 -
C++知识点38——拷贝赋值运算符、析构函数、=default、阻止拷贝和赋值
一、拷贝赋值运算符介绍拷贝赋值运算符,先简单说下重载运算符的知识。重载运算符本质依然是函数的重载,重载运算符的函数名由operator关键字和运算符的符号组成,和其他函数类似,可以有形参和返回值。重载运算符函数的参数表示运算符的运算对象,因为拷贝赋值运算符必须定义为成员函数,所以,拷贝赋值运算符的左侧运算对象的地址必须绑定到this,右侧对象作为参数初始化重载运算符函数的形参。为了和内置类型的赋值保持一致,拷贝赋值运算符通常返回一个左侧运算对象的引用注意:如果一个类中有的成员是const的,那么原创 2020-11-03 09:04:35 · 2150 阅读 · 0 评论 -
C++知识点37——拷贝构造函数
无论是C++自定义的类还是STL内部的容器类,会显式的定义类的对象在拷贝、赋值和销毁时执行的操作,一个类通过五个成员函数来控制这些操作:拷贝构造函数、拷贝赋值运算符、移动构造函数、移动赋值运算符和析构函数。其中,拷贝构造函数和移动构造函数定义了当用相同类型的一个对象初始化另一个对象时的操作,拷贝赋值运算符和移动赋值运算符定义类用一个对象给另一个相同类型的对象赋值时的操作,析构函数定义了类的对象被销毁时的操作。上述五个成员函数如果没有自定义、那么,编译器将会自动定义这些操作,但是编译器定义的版本可能并不是原创 2020-11-02 11:25:24 · 1002 阅读 · 0 评论 -
C++知识点36——使用智能指针的注意事项(下)
四、智能指针与容器当把shared_ptr对象放入一个容器中时,会调用shared_ptr的拷贝构造函数并且引用计数+1int main(int argc, char const *argv[]){ shared_ptr<test> sp=make_shared<test>(); vector<shared_ptr<test>> vsp; vsp.push_back(sp); cout<<sp.use_count()<&原创 2020-10-26 14:58:19 · 832 阅读 · 0 评论 -
C++知识点35——使用智能指针的注意事项(上)
一、shared_ptr, weak_ptr和unique_ptr之间的赋值操作1.shared_ptr之间的赋值操作当使用shared_ptr对象进行赋值时,左值会指向新的对象,所以左值的引用计数-1,右值的引用计数+1,如果左值的引用计数为0,则会对象会被释放,调用析构函数class test{public: test():a(9){cout<<__func__<<endl;} test(int a_){ cout<<"test(int a)原创 2020-10-24 19:14:38 · 619 阅读 · 0 评论 -
C++知识点34——动态内存与智能指针
一、动态内存动态内存所在的位置在堆区,由程序员手动分配并手动释放,而不像栈内存由系统分配和自动释放C++通过new运算符为对象在堆上分配内存空间并返回该对象的地址,并用delete运算符销毁对象并释放对象所占的动态内存,如果分配动态内存后没有手动释放会产生内存泄露示例void newexample(){ int *pi=new int; string *ps=new string; cout<<*pi<<","<<*ps<<endl;原创 2020-10-18 17:32:57 · 596 阅读 · 0 评论 -
C++知识点33——使用C++标准库(无序关联容器unordered_(multi)map,unordered_(multi)set)
C++中,无序关联容器一共有4个,unordered_map,unordered_set,unordered_multimap,unordered_multiset这四个和有序关联容器最大的区别就是无需关联容器没有根据key或者value进行排序,内部元素是无序的,无序关联容器只能表明元素是否在容器中,并不能对元素进行排序无序关联容器用哈希表来实现,如下图通过哈希函数,将元素放在对应的桶中,每个桶是一个链表,所以一般情况下,无序容器的查找速度快于关联容器unordered_map和.原创 2020-09-24 09:00:27 · 502 阅读 · 0 评论 -
C++知识点32——使用C++标准库(关联容器set和multiset的初始化,赋值,查找,添加,删除与迭代器失效)
关联容器map和multimap已经在博客https://blog.csdn.net/Master_Cui/article/details/108690877和https://blog.csdn.net/Master_Cui/article/details/108696599中介绍了set,multiset和map,multimap的区别就是前两者的key和value都是一个类型的值,是一体的,而后两者的key和value分别是两个类型的值set和multiset容器中的元素依然按照key进行排序,原创 2020-09-21 16:03:00 · 473 阅读 · 0 评论 -
C++知识点31——使用C++标准库(关联容器multimap及其初始化,赋值,查找,添加,删除与迭代器失效)
关于关联容器map已经在博客https://blog.csdn.net/Master_Cui/article/details/108690877中介绍完了multimap和map非常类似,容器中的元素按照key进行排序,只不过map的key不能重复,而multimap的key可以重复map和multimap使用前,都要添加头文件#include <map>1.multimap的声明与初始化template < class Key, .原创 2020-09-20 18:44:57 · 816 阅读 · 1 评论 -
C++知识点30——使用C++标准库(关联容器map及其初始化,赋值,查找,添加,删除与迭代器失效)
一.关联容器简介关于顺序容器和关联容器的区别已经在博客https://blog.csdn.net/Master_Cui/article/details/107427911中提过C++标准库中的关联容器一共有八个,分别是map,multimap,set,multiset,unordered_map,unordered_set,unordered_multimap,unordered_multiset其中,前四个是有序关联容器,简称关联容器,map,multimap,set,multiset默认原创 2020-09-20 11:14:55 · 1211 阅读 · 0 评论 -
C++知识点29——使用C++标准库(迭代器适配器)
在上一篇文章https://blog.csdn.net/Master_Cui/article/details/108512730谈到的迭代器是基本的五种类型的迭代器但是随着C++标准库的扩展,又实现了一些迭代器,这些迭代器的操作和之前的五中操作类似,所以成为迭代器适配器,类似容器适配器常用的容器适配器有三种:1.插入迭代器:该迭代器能向容器中添加元素2.流迭代器:该迭代器能操作C++标准库中的IO对象3.反向迭代器:从容器尾元素向首元素反向移动的迭代器一、插入迭代..原创 2020-09-13 19:25:49 · 326 阅读 · 0 评论 -
C++知识点28——使用C++标准库(再谈迭代器)
一、迭代器的种类C++中的容器以及泛型算法会大量的使用迭代器目前已经出现的迭代器有一下几种1.输出迭代器 (OutputIterator)输出迭代器类似于输出流(只能向输出流中写入数据),只能向输出迭代器中写入数据,输出迭代器的常用操作如下2.输入迭代器 (InputIterator)输入迭代器类似于输入流(变量只能读取输出流中的数据),只能向输出迭代器中写入数据,输入迭代器的常用操作如下3.前向迭代器 (ForwardIterator)加强版的输入迭..原创 2020-09-10 14:03:17 · 396 阅读 · 0 评论 -
C++知识点27——使用C++标准库(常用的泛型算法2)
接上一篇博客https://blog.csdn.net/Master_Cui/article/details/108404257八、删除元素template <class ForwardIterator, class T>ForwardIterator remove (ForwardIterator first, ForwardIterator last, const T& val);template <class ForwardIterator, class Un原创 2020-09-09 15:44:18 · 201 阅读 · 0 评论 -
C++知识点26——使用C++标准库(常用的泛型算法1)
C++中实现了很多的泛型算法,大约100多个,使用前要添加#include<algorithm>下面介绍的基本可以满足绝大部分需求,其他的用到再查一、计数算法1.counttemplate <class InputIterator, class T>typename iterator_traits<InputIterator>::difference_type count (InputIterator first, InputIterator l.原创 2020-09-04 15:04:11 · 524 阅读 · 0 评论