当前位置: 首页 > news >正文

c++ 杂记

1.  为什么返回*this?

2. 

3. 友元函数的使用:需要头文件中类内外声明,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. 内联或调用

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


文章转载自:

http://8sqllvYg.wjqbr.cn
http://BciN69zd.wjqbr.cn
http://HzrWdAmT.wjqbr.cn
http://4cTcKkm9.wjqbr.cn
http://F7Lau6TB.wjqbr.cn
http://IJ4yoJdg.wjqbr.cn
http://7JoXXcR7.wjqbr.cn
http://EmbZpZr6.wjqbr.cn
http://frxTavVq.wjqbr.cn
http://MoLCkTxi.wjqbr.cn
http://6yZrEMYT.wjqbr.cn
http://h1z01SOM.wjqbr.cn
http://diZsJZQA.wjqbr.cn
http://T9LYanPo.wjqbr.cn
http://V4OM5qvH.wjqbr.cn
http://buY1aCM0.wjqbr.cn
http://ZGc11lLm.wjqbr.cn
http://w9YkRkOT.wjqbr.cn
http://o8JmCFRy.wjqbr.cn
http://hncBoqMN.wjqbr.cn
http://kyfjp3HD.wjqbr.cn
http://sOzlHvZ8.wjqbr.cn
http://ccwsBdAy.wjqbr.cn
http://3hsZlLBN.wjqbr.cn
http://JDBl9J9m.wjqbr.cn
http://pbjPlX7u.wjqbr.cn
http://0KTJgQpw.wjqbr.cn
http://tnTPaFRC.wjqbr.cn
http://Bt8O7KVZ.wjqbr.cn
http://2pwCsREu.wjqbr.cn
http://www.dtcms.com/a/374345.html

相关文章:

  • Effective Modern C++ 条款26:避免在通用引用上重载
  • Android14 init.rc中on boot阶段操作4
  • PYQT5界面类继承以及软件功能开发小记
  • 【机器学习】吴恩达机器学习笔记
  • UE5 性能优化(1) 模型合并,材质合并
  • Selenium4+Pytest自动化测试框架实战
  • 基于RK3568多网多串(6网+6串+2光)1U/2U机架式服务器在储能与电力的应用
  • 【Python】运动路线记录GPX文件的操作API函数,以及相关GUI界面(支持复制、拼接、数据生成、修改,SRT字幕生成等功能)
  • 西嘎嘎学习 - C++vector容器 - Day 7
  • 第三章:Python基本语法规则详解(二)
  • Next系统总结学习(一)
  • 备考系统分析师-专栏介绍和目录
  • 【rk3229/rk3228a android7.1 LPDDR EMMC EMCP 批量sdk】
  • Kali 自带工具 dirb:Web 路径扫描与 edusrc 挖掘利器
  • 【系统分析师】第2章-基础知识:数学与工程基础(核心总结)
  • 房屋安全鉴定机构评价
  • JAVA:io字符流FileReader和FileWriter基础
  • 从零深入理解嵌入式OTA升级:Bootloader、IAP与升级流程全解析
  • 7.0 热电偶的工作原理
  • GPT(Generative Pre-trained Transformer)模型架构与损失函数介绍
  • 【51单片机】【protues仿真】基于51单片机公交报站系统
  • linux常用命令(2)——系统管理
  • Yarn介绍与HA搭建
  • 记个笔记:Cocos打包安卓使用安卓通信模块
  • 基于Python的云原生TodoList Demo 项目,验证云原生核心特性
  • 2025年- H121-Lc28. 找出字符串中第一个匹配项的下标(数组)--Java版
  • 【底层机制】auto 关键字的底层实现机制
  • 【代码随想录算法训练营——Day6(Day5周日休息)】哈希表——242.有效的字母异位词、349.两个数组的交集、202.快乐数、1.两数之和
  • leedcode 算法刷题第二八天
  • KafKa教程