c++备忘录

本文探讨了C++编程中的几个关键概念:1) 模板类的模板成员函数的外部定义,需指定两次模板参数;2) 宏定义中的`#`用于字符串化,`##`用于拼接,`#@`在GCC中不支持;3) 匿名命名空间的作用,以及如何在版本控制中利用它;4) 使用`#pragma pack(n)`进行内存对齐的控制。了解这些细节能够帮助开发者更好地掌握C++编程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#1.模板类的模板成员函数

template <typename type1>

class C {

public:

template <typename type2>

void f();

}

如果需要在类外定义函数f时,要这样写:

template<typename type1, typename type2>

void C<type1>::f() {...}

而不能写成

template<typename type1>

template<typename type2>

void C<type1>::f() {...}

#2.宏定义中的“#”,“##”,“#@”用法

“#”用于将宏参数转化为字符串,即在宏参数的两边加上双引号。例如:

#define STR(x) #x
int abc = 1;
cout << STR(abc) << endl;

上面会输出程序会将会输出字符串“abc”而不是变量abc的值。

“##”用于宏参数之间的连接或宏变量与其他代码的连接。例如:

#define VAL1(x) x##1
#define VAL2(x, y) x##y
int abc1 = 1;
cout << VAL1(x) << endl;
cout << VAL2(x, 1) << endl;
两个输出语句都会输出变量abc1的值。

“#@”是将宏参数转成字符,即在宏参数的两边加上单引号,不过gcc不支持。

在使用“#”,“##”,“#@”时,如果宏参数本身也是宏的话,该宏参数是不会进行宏展开的,这里用一个简单的例子解释下:

#define STR(x) #x
cout << STR(__LINE__) << endl;
上面的代码并不会将宏__LINE__展开,因此得到的输出是“__LINE__”,而不是当前代码行号的字符串表示。为了能够将__LINE__展开,我们需要借助转换宏。
#define _STR(x) #x
#define STR(x) _STR(x)
cout << STR(__LINE__) << endl;
这样宏__LINE__就会在调用STR的时候展开,因此传给_STR的就是__LINE__的值了。


#3. 匿名命名空间

匿名空间中定义的函数或变量的作用域被限制在文件范围内,功能等同于用static修饰这些函数或变量。例如:

#a.cpp
void f1(){...};
static void f2(){...};
namespace {
  void f3(){...};
}
#b.cpp
extern void f1(); //ok
extern void f2(); //链接出错
extern void f3(); //链接出错


#4. 内联命名空间(c++11)

当父命名空间中定义了一个嵌套的普通命名空间时,访问该嵌套命名空间中函数或变量等时需要使用域作用符。但当该嵌套命名空间换成一个内联命名空间时,该内联命令空间中的函数或变量等自动成为父命名空间的成员,访问时不需要域作用符。版本控制场景下可能会需要这个特性,下面举个例子说明:

namespace Pro {
  namespace v1 {
    void f1();
    void f2();
  }
  inline namespace v2 {
    void f1();
  }
}

当你的项目版本1提供两个函数f1和f2,但版本2修改f1并且去掉了f2,这时你如果调用Pro::f1那么调用的函数是内联命名空间v2中的f1,并且调用Pro::f2会报错,如果你确实需要用到老版本中的函数,你可以这样调用:Pro::v1::f1和Pro::v1::f2。

#5.对齐

编译器中提供了#pragma pack(n)来设定变量以n字节对齐方式。n字节对齐就是说变量存放的起始地址的偏移量有两种情况:第一、如果n大于等于该变量所占用的字节数,那么偏移量必须满足默认的对齐方式,第二、如果n小于该变量的类型所占用的字节数,那么偏移量为n的倍数,不用满足默认的对齐方式。结构的总大小也有个约束条件,分下面两种情况:如果n大于所有成员变量类型所占用的字节数,那么结构的总大小必须为占用空间最大的变量占用的空间数的倍数;否则必须为n的倍数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值