在实际生产中,日志是非常重要的调试工具,日志内容至少需要包括时间戳、日志级别、日志内容 推荐的日志库有: google/glog: C++ implementation of the Google logging...message"); LOG(logger, LogLevel::FATAL, "This is a fatal message"); return 0; } 这意味着我们需要一个单例模式的实现...,需要将类实例静态化,由一个静态函数返回类实例的引用,由于静态变量只会初始化一次,所以每次返回的都是同一个实例 同时我们希望能够保留可以更改类实例初始化的参数,例如日志文件名,因此需要一个初始化的静态函数来进行类实例的初始化...Logger::getInstance().log(level, message, __FILE__, __LINE__, __FUNCTION__) #endif //LOGGER_H 代码维护在GitHub...MaolinYe/Logger: C++实现的日志类,记录日志写入时的时间,可选的日志级别(DEBUG / INFO / WARN / ERROR / FATAL),日志内容,日志写入时的代码文件,
采用模板类实现的好处是,不用拘泥于特定的数据类型。就像活字印刷术,制定好模板,就可以批量印刷,比手抄要强多少倍! 此处不具体介绍泛型编程,还是着重叙述链表的定义和相关操作。 ...本文采用的是第4种结构类型 /************************************************************************* 1、复合类:在Node类中定义友元的方式...在List内部定义Node类,但是Node的数据成员放在public部分,使List 和Node均可以直接访问Node的成员 **************************************...private: LinkNode *head; }; 单链表的模板类定义 使用模板类需要注意的一点是template必须定义在同一个文件,否则编译器会无法识别。...如果在.h中声明类函数,但是在.cpp中定义函数具体实现, 会出错。所以,推荐的方式是直接在.h中定义。
一、用模板实现单例模式 在前面的文章中,用过多种方法实现单例模式,现在用模板方式来实现: 为了实现线程安全,需要在linux 下使用pthread_mutex_t 加锁,请使用g++ 编译并需要链接 -...即 将Singleton 实现为模板类,将ApplicationImpl 类包装成单例模式类,可以看到构造函数和析构函数都只调用了一次。...程序使用一个小技巧,用axexit 函数注册了程序结束时需要调用的函数。...二、模板方式实现动态创建对象 在前面的文章曾经使用宏定义的方式实现动态创建对象,现在在 DynBase.h 中用模板类将宏定义替换掉,其他代码不变: //class Register //{ //public...参考: C++ primer 第四版 Effective C++ 3rd C++编程规范
在 C++ 中调用一个函数、使用一个类、实例化一个模板时,对传入的参数、使用的时机,往往会有很多 限制 (constraint/restriction)(例如,数值参数不能传入负数、对象的访问不是线程安全的...漫谈 C++ 的各种检查 1 编译时检查 编译时静态检查,主要依靠 C++ 语言提供的 语法支持/静态断言 和 编译器扩展 实现 —— 在检查失败的情况下,编译失败。...1.2 可拷贝性检查 C++ 语言本身有很多编译时检查(例如 类的成员访问控制 (member access control)、const 关键字 在编译成汇编语言后,不能反编译还原),但 C++ 对象默认是可拷贝的... (singleton) 操作 对于 非泄露型 `base::Singleton`,会在 `base::AtExitManager` 注册 “退出时销毁单例对象” 如果主线程先退出,在 base::AtExitManager... 中销毁单例,导致仍在运行的 non-joinable 线程再访问单例时,出现野指针崩溃 实现的 核心思想 也很简单: 通过 TLS 记录 当前线程的限制情况(每种限制用一个 TLS bool 存储)
单例模式看起来简单,但是需要考虑的问题却很多。 保证一个类仅有一个实例,并提供一个该实例的全局访问点。...实现 单例模式的实现有很多中,我们来看看一些常见的实现。某些实现可能是适合部分场景,但并不是说不能用。...用模板包装单例 从上面已经知道了单例模式的各种实现方式。但是有没有感到一点不和谐的地方?...如果我class A需要做成单例,需要这么改造class A,如果class B也需要做成单例,还是需要这样改造一番,是不是有点重复劳动的感觉?利用c++的模板语法可以避免这样的重复劳动。...总结 单例模式本身十分简单,但是实现上却发现各种麻烦,主要是多线程编程确实是个难点。而对于c++的对象模型、内存模型,并没有什么深入的了解,还在一知半解的阶段,仍需努力。
我们以静态数组为例;在没有非类型模板参数时,我们采用如下方式来定义一个静态数组: #define N 10 template class arr { public: //... private...stack 进行声明和定义分离,注意: 1、类模板的外部成员定义不得具有默认参数,即类模板声明与定义分离时不能成员函数不能使用缺省参数; 2、类模板的成员函数在分离定义时必须指明该函数是属于那个类的...但是当我们编译运行的时候我们发现分离定义的所有成员函数都出现了链接性错误: 造成这种错误的原因如下: 在C语言 程序环境和预处理 那一节我们学习了一个 .c/.cpp 程序要变成 .exe 可执行程序一共要经历四个步骤...同时,预处理、编译、汇编这几个阶段每个源文件 (.c 文件) 都是独立进行的,只有在链接时才会将这几个目标文件合并到一起形成可执行程序。...模板的缺点: 模板会导致代码膨胀问题,也会导致编译时间变长; 出现模板编译错误时,错误信息非常凌乱,不易定位错误; ----
2,类模板 函数模板很好理解,那么类模板是什么呢? 可以在类模板的内部或外部定义成员函数。 如果在类模板的外部定义成员函数,则会像定义函数模板一样定义它们。...于是我们可以总结出语法: 1,使用 template 对类声明和类定义进行修饰。 2,类内部需要使用模板类型时,直接使用相应的模板形参名。...(编译避坑) C++ 的模板类在没有被使用之前,编译器完全不知道它会占用多少空间!...简单化使用.h头文件和.cpp文件分类声明时,几乎确定会报链接错误。...+ 标准库 std::condition_variable 【Example】C++ 用于编译时封装的 Pimpl 演示 (编译防火墙 Private-IMPL) 【Example】C++ 单例模式 演示代码
本文我们将探讨如下内容: 单例模式的基本实现:包含单例模式的实现,线程安全,以及生命周期等 单例模式的模板实现, 多模块调用单例存在的问题 单例模式的基本实现 在程序开发中,比较常见的单例就是程序启动的相关配置信息了...线程安全 如果是如下方式使用static对象方式实现的单例模式,在C++ 11之前是非线程安全的,而在C++ 11之后是线程安全的。...不过本人认为这一种的模板化实现,并不是一个特别好的方案,我也并不会优先选择模板化的单例模式实现,主要有两点原因: 模板参数接受的类,可以是这种:默认暴露给用户,可以构造,拷贝,赋值的类,这样便可以重新创造多个对象...当使用模板实例化的时候,同一种模板参数的类,在多个不同的模块中其实都会有自己的实例化对象。...对于非模板的实现,一般将单例实现的类从模块导出,将实现放在.cpp文件中,那么这种多个工程对同一种单例的类只会有一个实例化对象。个人觉得这一点比较重要,需要读者多多体会。
6、模板的实现可以写在.h文件中吗? 7、C++模板类代码只能写在头文件? 这个问题,实际上我几年前就遇到了。最近写个模板类玩的时候,再次遇到。...那么当我把模板声明和实现分开的时候,这个即时过程因为编译器只能通过代码include“看到”头文件而找不到模板实现代码,所以会产生链接问题。这也是为什么几乎都会建议模板类和声明和实现都写在头文件。...如果编使用模板代码的时候,通过include包含“看不到”模板的实现代码,这些所有的缺失,到链接阶段就无法完成。 所以最后的结论是:请老老实实把模板的实现和声明都写在头文件吧。...3、模板你在项目中使用的多吗? C++面试6 1、派生类怎么调用基类的虚函数版本? C++ primer 这本书上有这么两句话“派生类虚函数调用基类版本时,必须显式使用作用域操作符。...读写前后加锁处理 6、单例模式 指针: 会出现多线程访问的new多个对象的问题 static 成员变量:所有类都使用同一个对象 7、你目前这份工作解决的最大难题是什么,谈谈你是怎么解决的?
(复习一个知识点,当类中成员变量出现const修饰,引用的成员变量,或自定义对象没有合适的默认构造函数时,必须在初始化列表的位置显示初始化,不可以在构造函数内部对成员变量赋初值) 除此之外还需要说明的一个问题是关于释放单例对象资源的话题...,单例对象是在堆上开辟出来的,所以必须由程序员手动释放该空间资源,那我们能不能在Singleton的内部实现一个析构函数,然后delete掉单例对象呢?...所以下面代码中有两种方式,第一种就是自己实现一个DelInstance接口,当我们不想在使用单例对象时,可以手动调用这个接口来释放单例对象的空间资源。...另一种就是实现一个内部的垃圾回收类GC,用这个类来定义出静态对象_gc,这个_gc是单例类的成员变量,所以当程序结束时,静态对象_gc的生命结束,会自动调用自己的析构函数,而GC本身就是内部类,可以直接访问到静态指针...懒汉模式→堆 a.单例对象是在需要的时候才会被创建,所以不会影响程序的启动速度,执行流在进入main函数之后,调用GetInstance时,单例对象才会被创建。
C++搞出来非类型模板参数的array类,实际对标的就是C语言的静态数组,array的第二个模板参数就是非类型模板参数N,我们在定义静态数组时,除C语言外的定义方式,还可以用array类来定义一个对象,...C++觉得C语言的检查机制不够严格,使用者在使用时有可能会因为越界访问导致程序出现意料不到的错误,所以C++出来了array类,array无论对于越界读还是越界写,他都可以检查出来,本质是因为他的检查机制是...在main函数的测试用例中前两次的打印结果都是正常的,因为日期之间进行比较时可以直接调用日期类的运算符重载,并且Less是一个函数模板,可以接收所有的类型的比较,包括内置类型和自定义类型。 2....在使用类模板显示实例化的地方,只有.h文件展开,而没有.cpp文件,因为在链接之前,各源文件之间是互不联系的,所以即使你显示实例化了类模板,但在类模板真正定义的地方却没有实例化,所以在链接的时候.cpp...里面没有实例化出来的类模板,自然链接就会出问题,因为你用了一个并没有真正实例化出来的类,编译器就会报链接错误。
---- 泛型编程 引子 对于一组功能相同单参数类型不同的函数,在C语言中只能写多个不同名的函数来实现; void Swapc(char& a, char& b) { char tmp = a; a...,否则会报错 所以编译器的原则是在最满足匹配时,优先调用显式实现的; ---- 类模板 接下来介绍类模板; 相比函数模板,类模板使用更加广泛 引子 类模板的出现是为了解决一些问题,与函数模板相似...原因分析 类模板分离编译会报链接错误 一般建议类模板在同一个文件中声明和定义分离,这是最好的方式了,达到了类中简洁只有函数声明,同时没有各种错误; 来看看类声明和定义分离且不在一个文件会遇到的问题...这牵扯到了多个源文件的编译链接过程 链接错误,说明不是语法问题,而是链接时,test.o在class.o中找不到要调用的类模板实例化出来的函数,即类模板没有实例化处具体的函数,class.o符号表中也就没有相应函数的地址...,而这又发生在链接阶段,导致链接错误; 解决方法 在函数定义文件中主动显式实例化 这是一个不太好(实用)的方法 既然链接错误是因为,类模板成员函数只有声明显式实例化了,那么我们也在类模板成员函数定义文件内显式实例化即可
(一)、让自己习惯C++ 一、C++语言联邦 多重范型编程语言:过程式、面向对象式、函数式编程、泛型编程、模板元编程。...使用时调用,单例模式,多线程不安全。 (二)、构造/析构/赋值运算 五、C++默认编写的函数 默认构造、复制构造、析构、赋值运算符。...七、多态基类声明虚析构函数 (不)具有多态性质基类(不)需要虚析构函数; 八、不让异常逃出析构 异常时终止或者吞下; 将可能抛出异常的代码提供给用户管理; 九、不在构造和析构中调用虚函数 调用后仅仅是自身的虚函数...四十二、typename双重含义 模板声明中与class没有任何区别; 嵌套从属类型的显式指定,不能出现在基类列表和初始化列表中; ?...四十六、类型转换时为模板定义非成员函数 对于模板化的类要支持双操作运算符重载,首先必须是非成员函数,另外为了能让模板具体化必须将函数定在类体内部,因此只能将之声明为友元类型。
运行结果: 错误分析: C/C++程序要运行,一般要经历一下步骤: 预处理 -> 编译 -> 汇编 -> 链接 的过程....链接:将多个obj文件合并成一个,并处理没有解决的地址问题 那么对于模板的分离编译操作 模板参数没有得到 类型的实例化,就无法得到地址,这也就导致了在链接过程中的链接错误....它允许定义类型和函数,具体实现可以在编译时根据实际数据类型进行实例化。C++的模板主要分为函数模板和类模板两种。 函数模板允许定义通用函数,其类型可以在编译时由实参推断得出,或者显式指定。...函数模板可以与普通函数重载,以满足不同的需求。 类模板允许定义通用类,其类型可以在编译时由实参推断得出,或者显式指定。类模板可以在编译时生成具体类的实例,以满足不同的需求。 【优点】 1)....模板会导致代码膨胀问题,也会导致编译时间变长 2). 出现模板编译错误时,错误信息非常凌乱,不易定位错误 3). 模板也可能会增加代码的复杂性和可读性。
非类型形参:用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用。...这是因为在编译时,非类型模板参数需要在编译器确定其值,而浮点数、类对象以及字符串在编译时无法确定其值。...注: C++20之前,只允许整型做非类型模板参数 C++20之后,支持浮点数等其他内置类型 2.模板的特化 2.1引例 引例 给一个日期类: //日期类 class Date { public...: 这是因为C/C++程序运行一般需要经历以下步骤: 预处理——编译——汇编——链接 预处理:在编译之前,预处理器对源文件进行处理,包括宏展开、头文件包含等操作。...也会导致编译时间变长 出现模板编译错误时,错误信息非常凌乱,不易定位错误 以上就是今天进阶模板所有的内容啦~ 完结撒花
2.使用函数模板在链接时出错 在C++程序设计中,在一个源文件中定义某个函数,然后在另一个源文件中使用该函数,这是一种非常普遍的做法。...但是,如果定义和调用一个函数模板时也采用这种方式,会发生编译错误。...这样,在链接的时候就会出现func没有定义的错误。 3.解决办法 3.1将函数模板的定义放到头文件 一个简单的解决办法就是将函数模板func的定义写到头文件func.h中。...注意: 这样做,如果在多个目标文件中存在相同的函数模板实例化后的模板函数实体,链接时并不会报函数重定义的错误,这与普通函数不同,因为编译器会对实例化后的重复的模板函数实体进行优化,只保留一份代码实体。...当类模板的成员函数的实现定义在源文件中,通过模板类的对象调用成员函数时也会出现找不到函数定义的错误,可以使用同样的方法解决,不再赘述。
C++特性 不要使用异常。 不要使用rtti(运行时类型信息:即typeinfo结构,dynamic_cast或typeid运算符,包括引发异常)。 谨慎明智地使用模板,不仅仅是因为可以使用。...当重新实现一个虚方法时,不要再在头文件中放入virtual关键词。在Qt5中,在函数声明;或{之前使用override关键词修饰它们。...避免的操作 不要继承模板/工具类 由于析构函数不是virtual,这会导致潜在的内存泄漏问题。 这些符号没有被导出(大部分是内联的),会导致报符号冲突的编译错误提示。...= c.cend(); ++it) /* 正确 */ Q[Core]Application是单例类。一次只能有一个实例。...确保使用static本地化到编译单元的名称具有内部链接。不幸的是,对于在匿名名称空间中声明的名称,C++标准要求进行外部链接。
此时编译main.cpp单元不会报错,但链接就会出现add函数未定义的错误。...,因此在使用类模板的时候,首先会初始化类模板,同时初始化类模板相应的构造函数,使用类模板的实例调用相应的成员函数时,才会初始化类模板的成员函数。...如果类模板的成员函数的定义与类的定义不在同一个编译单元中(分离式编译),此时调用类的成员函数便会出现未定义的错误。而当我们像代码中那样在某个地方显式的调用它的时就不会出现此类问题了。...c++primer上面只说了类模板的成员函数可以不在头文件中定义,却始终感觉说得不清不楚,因为实际上像普通类那样类的定义与实现放在不同的文件中的话,是会链接出错的。...总之,若你不想出现任何未定的错误,将类模板或函数模板的定义与声明放在同一个文件中就行了。
【1】指针【2】数组【3】操作符4】动态内存管理【5】内存函数大全【6】文件操作函数 【7】程序的编译链接预处理详解【8】数据在内存中的处理 一.缺省函数 运用场景: 例:在通讯录项目时,可以省去初始化函数...Vector s1; Vector s2; 注意区分: 在类中:类名等同于类型 在类模板中:类型是类型,类名是类名 例如:在下面代码中,类模板中函数放在类外进行定义时,...例:商家,骑手,用户之间的关系 面向过程更多指的是实现目的过程步骤:上架->点餐->派单->送餐 通俗而言:即对象与事的区别 十一.面向对象的三大特征 (含类的概念) 面向对象的三大特性:...在C++语言中实现封装 封装本质上属于一种管理。例:计算机设计中的开机键,usb插口等等,让用户通过这些和计算机交互。而实际工作的是硬件元件。...在C++中实现封装,可以通过类和操作数据的方法进行结合,通过访问权限(访问限定符)来隐藏对象内部实现细节,控制哪些方法可以在类外部直接被使用。
3、template C++,泛型编程,衍生出模板元编程(在各个新标准中逐步完善)。4、STL,包括容器、迭代器、算法与函数对象。...,出问题时无法定位到它。...更加可预测并且类型安全的写法是,对于定义常量,使用const对象(对于一系列常量,使用枚举或枚举类,而不是一系列#define),对于定义函数,使用模板内联函数。...2、成员初始列的排列顺序应与在类中的声明次序一致,因为成员初始化顺序只与后者有关,前者若与后者不一致的话可能导致误解。...解决方法也很简单:将每个non-local静态变量移到自己的专属函数内,这些函数返回该静态变量的引用,用户使用这些函数而非直接使用变量(类似单例模式)。
领取专属 10元无门槛券
手把手带您无忧上云