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. 内联或调用

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

相关推荐
汉克老师16 分钟前
CSP-J 2026 初赛试题解析(第一部分:选择题(8-15))精讲
c++·csp-j·小学生·学c++编程
wabs6661 小时前
关于二叉树【力扣572.另一棵树的子树的思考】
数据结构·c++·算法·leetcode·二叉树
风合星语2 小时前
2026 ROS 2 Lyrical C++ 入门(五):Action 实战——任务反馈、取消与超时处理
c++·机器人·ros2·异步编程·lyrical
91刘仁德2 小时前
C++ 继承和多态 设计模式
c语言·c++·笔记
码行山野赴时序归途3 小时前
链表家族收官篇:循环链表
c语言·开发语言·数据结构·链表
景熙55233 小时前
单体项目编写思路和落地形式
java·开发语言
库玛西3 小时前
哈夫曼树与前缀编码:数据压缩的贪心核心
c语言·c++·笔记·考研
别动我齐刘海3 小时前
ROS2 Jazzy + C++ 实战路线——进阶学习3
c++·人工智能·vscode·python·算法·机器学习·机器人
0+1113 小时前
算法 --滑动窗口
c++·算法·leetcode
计算机毕设定制辅导-无忧学长3 小时前
《基于SpringBoot的未成年人健康知识科普平台的设计与实现》
java·开发语言·vue.js·spring boot·未成年人健康知识科普平台