c++随笔二
T const&
是常量引用(const reference)的语法,它的含义和用途:
T const&
的含义:
语法分解:
T
- 模板类型参数const
- 常量限定符,表示不可修改&
- 引用符号,表示引用传递
完整含义:
“对类型T的常量引用” - 即传入一个T类型对象的引用,且不能通过这个引用修改原对象。
为什么使用 T const&
?
1. 避免不必要的拷贝
// 不好的方式:值传递(会拷贝)
void push(T elem); // 每次调用都会复制整个对象// 好的方式:引用传递(不拷贝)
void push(T const& elem); // 直接使用原对象,无拷贝开销
2. 保证安全性
template <class T>
void Stack<T>::push(T const& elem) {// const& 确保我们不会意外修改传入的参数// elem = someValue; // 编译错误!不能修改elems.push_back(elem); // 只能读取elem的值
}
3. 性能对比示例
g++ -o const_reference_demo const_reference_demo.cpp
./const_reference_demo
T const&
详解:
1. 语法含义
void push(T const& elem);
// ↑ ↑ ↑
// | | |
// 类型T 常量 引用
T const&
= 对类型T的常量引用
2. 三种等价写法
T const& elem // 推荐写法
const T& elem // 常见写法
T const &elem // 空格位置不同,意思相同
3. 为什么使用 T const&
?
原因1:避免拷贝,提高性能
// 差的方式:值传递
void push(T elem) {// 每次调用都会拷贝整个对象!// 如果T是string,会拷贝整个字符串// 如果T是大对象,性能损失很大elems.push_back(elem);
}// 好的方式:常量引用
void push(T const& elem) {// 不拷贝!直接使用原对象// 无论T多大,都没有拷贝开销elems.push_back(elem); // 只在这里拷贝一次到容器中
}
原因2:保证参数安全
void push(T const& elem) {// elem = otherValue; // 编译错误!不能修改参数elem.someMethod(); // ✓ 可以调用const方法elems.push_back(elem); // ✓ 可以读取elem的值
}
原因3:可以接受临时对象
Stack<string> stack;
stack.push("hello"); // ✓ 临时字符串对象
stack.push(string("world")); // ✓ 临时string对象// 如果参数是 T&(非const引用),这些调用都会编译错误!
4. 与其他参数类型的对比
参数类型 | 拷贝开销 | 能否修改参数 | 能否接受临时对象 | 使用场景 |
---|---|---|---|---|
T elem | 有 | 能(拷贝) | 能 | 需要修改副本时 |
T& elem | 无 | 能(原对象) | 不能 | 需要修改原对象时 |
T const& elem | 无 | 不能 | 能 | 只读访问(推荐) |
5. 在你的栈代码中的具体应用
template <class T>
void Stack<T>::push(T const& elem) {// elem是对传入参数的常量引用// 1. 无拷贝开销 - 直接引用原对象// 2. 不能修改 - 保证参数安全// 3. 支持临时对象 - stack.push("hello")可以工作elems.push_back