c++ 杂记

  1. 为什么返回*this?
  1. 友元函数的使用:需要头文件中类内外声明,cpp文件中实现定义哦
cpp 复制代码
// Sales_data.h
#ifndef SALES_DATA_H
#define SALES_DATA_H

#include <string>

class Sales_data {
    std::string bookNo;
    int units_sold = 0;
    double revenue = 0.0;

public:
    // 只声明,不定义
    Sales_data& combine(const Sales_data&);

    // 友元函数:仅声明(friend 关键字 + 函数签名)
    friend Sales_data add(const Sales_data& lhs, const Sales_data& rhs);
    friend std::ostream& print(std::ostream& os, const Sales_data& item);
};

// 类外函数声明(必须!)
Sales_data add(const Sales_data& lhs, const Sales_data& rhs);
std::ostream& print(std::ostream& os, const Sales_data& item);

#endif

4.template

模板的定义必须放在头文件中,不是因为"被其他类使用",而是因为:

✅ 编译器在实例化模板时,必须"看到"完整的定义(而不仅仅是声明)

✅ 这与普通函数/类的"声明-定义分离"模型完全不同


🧩 一、普通函数 vs 模板函数:关键区别

❌ 普通函数:可以分离声明与定义

复制代码
// utils.h
void print(int x);  // 声明

// utils.cpp
void print(int x) {         // 定义
    std::cout << x << "\n";
}
  • 编译 main.cpp 时,只需要知道 print 存在(有声明)
  • 链接时,链接器找到 print 的定义

✅ 成功!


❌ 模板函数:不能这样分离!

复制代码
// utils.h
template<typename T>
void print(const T& x);  // 只有声明

// utils.cpp
template<typename T>
void print(const T& x) {        // 定义
    std::cout << x << "\n";
}

// main.cpp
#include "utils.h"
print(42);        // ❌ 编译错误!
print("hello");   // ❌ 编译错误!

为什么?

  • 编译器看到 print(42),需要生成 print<int>(int)
  • 但它只看到了声明,没看到定义
  • 所以无法生成具体代码
  • 链接时也找不到 print<int>,报 undefined reference

👉 模板不是函数,它是一个"生成函数的蓝图"


✅ 正确做法:定义放在头文件中

复制代码
// utils.h
#ifndef UTILS_H
#define UTILS_H

#include <iostream>

// 定义在头文件中
template<typename T>
void print(const T& x) {
    std::cout << x << "\n";
}

#endif

// main.cpp
#include "utils.h"  // 包含了完整定义
print(42);        // ✅ 编译器看到定义,可以实例化 print<int>
print("hello");   // ✅ 实例化 print<const char*>

🧠 二、为什么必须"看到定义"?

因为模板实例化发生在 编译期(compile time),而不是链接期。

编译器要做:

  1. 看到 print(42)
  2. 推导出 T = int
  3. 生成 函数代码:void print<int>(const int&)
  4. 内联或调用

👉 这个过程需要完整的函数体(定义),而不仅仅是签名。

相关推荐
程序喵大人15 小时前
【C++入门】编译链接模型 - 05 ODR 为什么会让重复定义变成工程炸点
开发语言·c++·编译链接·odr
weixin1997010801615 小时前
《淘宝TOP API:落地方案、接口边界与业务踩坑 —— 聚石塔内外价差 10 倍的真相》(附 Python 源码)
开发语言·python
前端 贾公子15 小时前
LangGraph == 图的状态(State)管理 (上)
java·开发语言·数据库
汉克老师16 小时前
CSP-S 2026 初赛试题解析(第一部分:选择题(8-15))精讲
c++·csp-s·小学生·学c++编程
_wyt00116 小时前
洛谷 P10112 [GESP202312 八级] 奖品分配 题解
c++·数学·gesp·八级
xuxigifxfh16 小时前
牛客:HJ170 01序列
java·开发语言·算法·华为机考
朝朝辞暮i16 小时前
C++ 第 33 课:事件循环——spin() 到底在干什么
开发语言·c++·算法
野生技术架构师16 小时前
牛客网互联网大厂 Java 高频面试题整理(持续更新)
java·开发语言
殷色玫瑰16 小时前
AVL树:从平衡因子到四种旋转的完整实现
c语言·数据结构·c++·算法·visualstudio
小师兄吃牛肉17 小时前
Java语法 | 多重循环
java·开发语言·python