首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

别在C++代码里乱打日志了,这才是正确的打日志姿势!

本文Jungle将用C++设计实现一个日志系统。 1 为什么需要日志 为什么需要日志?其实在引言中已经提到了,实际的软件项目的几乎每个过程,都离不开日志。...{ LOG_TARGET_NONE = 0x00, LOG_TARGET_CONSOLE = 0x01, LOG_TARGET_FILE = 0x10 }; Log作用域...只要是你想打印日志的地方,任何一个函数、任何一个文件,都应该而且必须可以打印。也就是说这个log类的对象(不妨叫做日志记录器),日志记录器必须是全局的! 光是全局的就够了吗?...你这个文件里有一个全局的日志记录器,输出日志到file.log文件里;另一个文件里也有一个日志记录器,也输出到file.log文件里……多个日志记录器同时往一个文件里写日志,这显然不合理。...,可以定义一些宏来简化函数的使用,本文不再赘述。

2.4K30

【C++指南】inline内联函数详解

C++为什么引入了inline来替代C语言中的宏 C语言实现宏函数也会在预处理时替换展开,可以提高程序的执行效率,但是宏函数实现很复杂很容易出错的,且不方便调试,C++设计了inline目的就是替代C的宏函数...作用域和链接性: 宏定义没有作用域的概念,一旦定义,在定义点之后的文件中都可以使用,这可能导致命名冲突。...inline函数具有和普通函数相同的作用域和链接性,可以很好地控制其可见性和使用范围。...类型安全:与宏定义相比,内联函数是真正的函数,具有类型安全检查,可以避免因类型不匹配导致的错误。 作用域明确:内联函数具有明确的作用域,而宏定义则是全局的,容易引发命名冲突。...编译器优化选择:inline只是对编译器的建议,编译器会根据函数的大小、调用频率以及自身的优化策略来决定是否进行内联。不同编译器关于inline什么情况展开各不相同,因为C++标准没有规定这个。

15810
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    C C++ const 全面总结

    在C++中,使用const关键字和使用预处理指令#define来定义常量是两种不同的方法,它们具有一些关键的区别: 类型安全:const 定义的常量具有明确的类型,可以进行类型检查。...这有助于避免类型相关的错误。 作用域限制:const 定义的常量有特定的作用域,通常是在它被声明的块中。这有助于避免命名冲突,并增加了代码的可维护性。...作用域控制:const 变量有特定的作用域,而 #define 没有作用域概念,它是全局替换。 调试:const 常量在调试时更容易追踪。...编译器优化:现代编译器通常能够对 const 常量进行优化,尤其是在它们没有被取地址时。 因此,在C++中,通常推荐使用const来定义常量,因为它提供了更好的类型安全、作用域控制和调试能力。...如果你需要全局替换或创建宏,用 define。在现代 C++ 中,一般推荐使用 const,因为它更安全、代码更清晰。 总结 const 关键字在 C++ 中有多种用途,可以提高代码的安全性和可读性。

    10910

    【C++】C++入门必备知识详细讲解

    使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突,namespace 关键字的出现就是针对这种问题的。...像 printf("%d\n", Young::sqrt);中,sqrt 前面的 :: 符号,叫做域作用限定符,意思是让编译器使用域作用限定符前面的命名空间中定义的东西。...ListNode 前使用,而不是在 struct 前使用;嵌套使用 namespace 是从右往左看,到指定的命名空间中去寻找; 虽然这种方法可以有效避免命名冲突问题,但是每次用的时候都要在前面加上域作用限定符...和 cin 必须包含头文件以及按命名空间使用方法使用 std ,其中 std 是C++标准库的命名空间名,C++将标准库的定义实现都放到这个命名空间中。...那么传引用返回有什么应用场景呢?我们常见的传引用返回可以用作修改返回对象,例如在单链表中,查找函数和修改函数可以合并在一起写,使用传引用返回,这样就既可以查找到想要查找的数据,又能修改想要修改的值。

    14310

    C++入门

    当我们使用::域作用限定符,相当于钥匙打开了栅栏,我们就从栅栏里面的内容寻找。...3、一个对象可以有多个别名 2、做返回值 补充知识点:C语言传值返回的机制 上面count函数返回值是n吗? 不是,返回值是n的拷贝。 为何?...出了函数作用域,返回对象就销毁了,不能用引用返回,否则结果是不确定的。 那传引用返回有什么用武之地呢? 引用返回和静态变量结合,(出函数作用域不会销毁的变量,不是在栈空间上创建的变量)。...第二个价值:可以修改返回值 引用返回的总结: 出了函数作用域,返回对象就销毁了,不能用引用返回,否则结果是不确定的。只有返回值在出函数作用域之后还在,才能用引用返回!...普通函数使用时,需要建立栈帧,而栈帧的建立是非常繁琐的。 因为宏函数缺点较多,所以C++在此基础上应运而生了内联函数。

    5910

    《C++进阶之路:探寻预处理宏的替代方案》

    在 C++编程的历程中,预处理宏曾经扮演了重要的角色。然而,随着 C++语言的不断发展和编程理念的进步,预处理宏的一些弊端也逐渐显现出来。那么,C++中的预处理宏的替代方案有哪些呢?...本文将深入探讨这个问题,为你揭示 C++编程中的新选择。 一、预处理宏的作用与弊端 预处理宏在 C++中有着广泛的应用。它可以用来定义常量、实现简单的函数式宏以及进行条件编译等。...首先,预处理宏缺乏类型安全性。由于宏是在预处理阶段进行文本替换,编译器无法对宏的参数进行类型检查。这可能导致一些难以察觉的错误,尤其是当宏的参数类型与预期不符时。 其次,预处理宏的作用域难以控制。...内联函数在编译时被展开,避免了函数调用的开销,同时也可以进行类型检查和优化。 与预处理宏不同,内联函数具有更好的类型安全性和作用域控制。...内联函数的定义通常放在头文件中,并且可以使用类的成员函数和命名空间来进行封装,避免命名冲突。

    7610

    程序员C语言快速上手——进阶篇(八)

    所谓作用域,实际上就是指有效范围。一旦离开这个源文件的范围,就相当于离开了该源文件的文件作用域。...既然静态局部变量这么好,那是不是可以滥用呢?还是回到上面的例子,如果你是公司特聘人员,一个月只需要上两天班,那么你有必要在公司楼下买一个固定的私人停车位吗?...基于这个特性,我们通常可以使用静态局部变量做计数器,如上例,每次调用get_count函数时,对静态局部变量count自增1,打印结果如下: 1 2 3 4 静态函数static关键字除了可以修饰变量,...大家要注意前面的措辞,全局变量在文件作用域内可见,即从变量被声明的下一行,一直到当前文件的末尾,它都可以被直接使用。...最后,需特别注意的地方是宏的名字,这里是_H_H3_,使用头文件包含这种机制时,宏定义的名字一定要独特,避免重复,以免导致各种不可预知的问题。

    94930

    【C++】C++基础语法

    在学习C++之前,或者说任意一门语言的时候,我们都要了解并学习它不同于其他语言的语法知识,这些有利于我们后期的学习,也对开始学习C++有非常重要的作用,接下来让我们开始这段旅程吧!...---- 前言 C++兼顾C语言的语法,在C++上,可以编写C的代码! C++基础语法呢,有非常多的细节,需要大家慢慢来摸索,仔细的回顾,反复的复习!...图二则是没使用域作用限定符,会首先找局部,局部没有找全局,全局就是库函数中的rand函数了,所以是随机值。  ...---- 4.std官方库定义的命名空间 一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中 C++中,我们使用的函数都在std命名空间里,所以在我们使用时,经常会这样:...在使用时,会反反复复的去写域作用限定符,所以为了避免重复,c++就新出现 using namespace std;什么意思呢??

    1.4K20

    【Rust 易学教程】第 1 天:Rust 基础,基本语法

    Rust 字符串是 UTF-8 编码的,可以包含任何 Unicode 字符。 什么是 卫生宏?卫生宏和普通宏的区别有点类似词法作用域函数和动态作用域函数的区别。...当相应的 Box 离开作用域时,通过 Drop 特性释放堆分配的内存。 越界访问会导致 panic,或者可以通过切片的 get 方法进行检查。 match 会要求所有 case 都要得到处理。...这样做的结果是标准库可以更小。https://lib.rs 这个网站可以帮助你找到更多第三方库。 rust-analyzer 对主要的 ide 和文本编辑器实现了支持。...String::new() 创建一个新的空字符串,可以使用push()和push_str()方法向其添加字符串数据。 宏是一种从动态值生成私有字符串的方便方法。它接受与 println!...有时使用宏作为替代方法。

    40120

    【C→C++】打开C++世界的大门

    熟悉C语言之后,对C++学习有一定的帮助,本章节主要目标: 补充C语言语法的不足,以及C++是如何对C语言设计不合理的地方进行优化的,比如:作用域方面、IO方面、函数方面、指针方面、宏方面等。...有的: 确实打印出来了,那那两个冒号是什么东西啊,为什么在a前面加了这个符号就打印全局a了? ,::叫做 作用域限定符。...使用作用域限定符指定对应的命名空间 第一个方法就是用我们上面提到的作用域限定符::指定其对应的命名空间,这样我们的程序就会直接去对应的命名空间里寻找cout,那找到了,就可以用了: 这样就可以了...函数重载 自然语言中,一个词可以有多重含义,人们可以通过上下文来判断该词真实的含义,即该词被重载了。 5.1 函数重载概念 在C++中呢引入了函数重载,这个也是C语言所没有的,那什么是函数重载呢?...一个变量可以有多个引用 这个我们在上面就提到了嘛,就好比一个人可以有很多别名。 b、c、d都是a的引用。 引用一旦引用一个实体之后,就不能再引用其他实体 什么意思呢?

    18910

    【C++】穿越编程岁月,细品C++进化轨迹,深化入门基石(续章)——揭秘函数缺省参数的魅力、函数重载的艺术、引用的奥秘与内联函数的效率

    ,而是引用操作符,那么为什么这个符号都已经用作取地址了,还要拿来给引用使用呢?    ...,而引用不初始化化就会报错    (2)一个变量可以有多个引用,也就是一个变量可以取多个别名,并且取别名后再对别名引用,这个引用还是原变量的引用    (3)一个引用一旦确定,就不能再更改为其它变量的引用...+编译器会在调⽤的地⽅展开内联函数,这样调⽤内联函数就不需要建⽴栈帧了,就可以提⾼效率 它就和我们C语言里面的宏函数差不多的作用,但是要比宏要更加稳定和可控,并且宏还不方便调试,C++中的内联函数就是为了替代宏函数...   不过我们要注意的是inline对于编译器⽽⾔只是⼀个建议,也就是说,你加了inline编译器也可以选择在调⽤的地⽅不展开,不同编译器关于inline什么情况展开各不相同,因为C++标准没有规定这个...,而非NULL    那么今天C++入门基础的知识(下)就分享到这里啦,欢迎点赞三连,有什么问题欢迎给我私信,我会尽快回复    bye~

    10900

    使用Go语言来理解Tensorflow

    Python绑定和Python库:这个绑定是由C++实现自动生成的,这样我们可以使用Python来调用C++函数。此外,这个库将调用融合到了绑定中,以便定义更高级别的API。 Java绑定。...提问时间: 关于Tensorflow的架构,我们学到了什么?节点完全是由被定义的作用域来标识的。作用域是我们从图的根到达节点的路径。...有两种定义节点的方法:在不同的作用域(Go语言)中定义操作或更改操作名称。 我们解决了重复节点名称的问题,但另一个问题显示在我们的终端上。 ? 为什么MatMul节点会出现错误?...T支持的类型:half,float,double,int32,complex64,complex128 输出形状:自动推断 说明文档 这个宏调用不包含任何C++代码,但它告诉我们,在定义一个操作时,尽管它使用了模板...我们可以从教程中阅读到,即使在使用模板T时,我们也必须对每个支持的重载显式地注册内核。内核是以CUDA方式对C/C++函数进行的引用,这些函数将会并行执行。

    1.5K100

    iOS学习——iOS 宏(define)与常量(const)的正确使用

    概述   在iOS开发中,经常用到宏定义,或用const修饰一些数据类型,经常有开发者不知怎么正确使用,导致项目中乱用宏与const修饰。你能区分下面的吗?知道什么时候用吗?...生命周期:这个变量能存活多久,它所占用的内存什么时候分配,什么时候收回。 作用域:这个变量在什么区域是可见的,可以拿来用的。 static分两种情况:修饰局部变量、修饰全局变量。...1、static修饰局部变量 局部变量:在函数/方法/代码块内声明的变量。它的生命周期、作用域都是在这个代码块内。...也就是其作用域是整个源程序。我们可以使用extern关键字来引用这个全局变量。 当全局变量使用static修饰时,其生命周期没有变,依旧是在程序结束时才销毁。但是其作用域变了。...现在只限于申明它的这个文件才可见。使用extern关键字无法引用这个全局变量。 全局变量本来是在整个源程序的所有文件都可见,static修饰后,改为只在申明自己的文件可见,即修改了作用域。

    1.8K31

    C++inline函数简介

    函数的的输入参数和返回值映射到调用方法的局部变量空间中; (4)如果inline函数有多个返回点,将其转变为inline函数代码块末尾的分支(使用GOTO)。...具体可以参考here。 (7)C++类成员函数定义在类体内为什么不会报重定义错误?...如果编译器发现被定义在类体内的成员函数无法被内联处理,也不会出现重定义的错误,因为C++中存在5种作用域的级别,分别是文件域(全局作用域)、命名空间域、类域、函数作用域和代码块作用域(局部域)。...当类成员函数被定义在类体内,那么其作用域也就被限制在类域,当然定义在类体外的函数作用域也是属于类域的。显然并不是因为作用域的原因而不会产生重定义的错误。 那么原因究竟是什么呢?...6.小结 可以将内联理解为C++中对于函数专有的宏,对于C的函数宏的一种改进。对于常量宏,C++提供const替代;而对于函数宏,C++提供的方案则是inline。

    2.1K20

    C++:C++入门基础

    使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的 5.1 命名空间的定义 我们来观察这个代码,为什么会出现这样的情况呢...我们的c++祖师爷本贾尼博士正是发现了c语言的这个缺陷,引入了命名空间这个概念,将命名空间包括的区域变成了一块新的域,避免了不同程序员的变量或者是函数名冲突的问题!!...又无法区分开了,还有一种方法 2、命名空间其实还可以嵌套使用 5.2 命名空间的使用 回到刚刚的场景,我们将我们两个的max都放在了自己的命名空间,避免的冲突,那该如何去使用呢??...命名空间的使用有三种方式: 1、指定命名空间访问 作用域限制符的作用其实就是限定这个变量的查找范围,比如: 上图中,局部有个max,全局有个max,cyx和ss的命名空间也分别有个max。...,就在::前面加上相应的命名空间,就可以了 2、使用using将命名空间中某个成员引入(部分展开) 有些时候,我们如果对一个命名空间里的变量使用频繁,每次都要写一个名字和一个作用域限定符,太麻烦了

    36610

    今天你学C++了吗——C++启航之入门知识

    我们使用命名空间的目的是对标识符的名称进行本地化,以 避免命名冲突或名字污染 。...,全局域,命名空间域,类域; 域影响的是编译时语法查找⼀个变量/函数类型出处(声明或定义)的逻辑 ,有了域隔离,名字冲突就可以解决。...、函数,就需要使用 作用域运算符( ::), 前面加上命名空间名。...》 比如:水浒传里面的林冲,外号豹子头; 》定义:类型& 引用别名 = 引用对象; 》这里用到了&这个运算符,我们前面使用它来取地址,这是因为C++中为了避免引入太多的运算符,会复用C语言的...~编译器不知道使用哪一个就会报错~ 例: 正确使用:使用 static 修饰普通函数 ♥♥♥本篇博客内容结束,期待与各位优秀程序员交流,有什么问题请私信♥♥♥ ♥♥♥如果这一篇博客对你有帮助~别忘了点赞分享哦

    6200

    静态作用域和动态作用域

    静态作用域和动态作用域 所谓作用域规则就是程序解析名字的方法。...其原因是在采用静态作用域规则的时候,对于函数的定义者来说,他可以通过阅读自己的代码很容易地知道他所使用到的变量当前绑定的具体实体是什么,而在使用采用动态作用域的语言时,则需要考虑这个函数被调用的时候该变量所对应的具体实体...其实说 C++ 完全是静态作用域语言是不完全正确的,C++ 的宏系统由于是直接展开,所以它是根据展开的位置来判定其值到底是多少,所以本身是类似于动态作用域的,例如: #define ADD_N(x) (...正如前文所述,动态作用域的实现其实是求值环境的动态绑定,要在一个静态作用域的语言中模拟出这个效果,我们可以自己用一个类管理这个环境。...也就是说我们应该这样写: auto& x = lang::DynamicScope::instanceOf("x"); x = "123"; 我们可以考虑使用一点 C++ 的宏,来逼近我们一开始想实现的效果

    2.1K10

    手撕C++入门基础

    我们在域作用限定符来创建结构体的时候 我们需要将这个操作符放到结构体类型的名称的前面 不同的域我们是能定义同名的,但是同一个域是不能定义同名的 • C++中域有函数局部域,全局域,命名空间域,类域;域影响的是编译时语法查找...宏定义的缺点: 为什么会有这个inline这个东西?...宏是替换机制的 ,在宏定义后面加分号的话就有问题了 // 为什么要加外⾯的括号? 不加外面的括号这个优先级就有问题了 // 为什么要加⾥⾯的括号?...在c++中使用nullptr来定义空指针可以避免类型转换的问题 用nullptr来定义空指针: //下面两个函数构成函数重载 void f(int x) { cout 使用nullptr来定义空指针可以避免类型转换的问题 return 0; }

    12610

    C++ 入门基础:开启编程之旅

    使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染。namespace关键字就是针对这种问题的。...2.namespace本质是定义出⼀个域,这个域跟全局域各自独立,不同的域可以定义同名变量。...这样C++函数调用就表现出了多态行为,使用更灵活。C语言是不支持同⼀作用域中出现同名函数的。...比如:水浒传中宋江,外号“及时雨”;林冲,外号“豹子头”; 类型&引用别名 = 引用对象; 这里引用也和C语言取地址使用了同一个符号&,大家注意使用方法角度区分就可以。...2.inline对于编译器而言只是⼀个建议,也就是说,你加了inline编译器也可以选择在调用的地方不展开,不同编译器关于inline什么情况展开各不相同,因为C++标准没有规定这个。

    5310

    【C++】入门基础(为C语言填坑)

    C语言有一些语法的不足,C++对C语言设计不合理的地方进行了优化,C++既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行面向对象的程序设计。...使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。...这个域跟全局域各自独立,不同的域可以定义同名变量。...使用命名空间有三种方式: 加命名空间名称及作用域限定符 int main() { printf("%d\n", yjz::rand); return 0; } 使用using将命名空间中某个成员引入...inline什么情况展开各不相同,因为C++没有规定这个。

    6510
    领券