Cpp / 引用的本质

一、答案

一个指针变量,即:T *const

二、分析

    int a = 0;
    int &b = a;  // int *const pb = &a;
    
    int c = 3;
    int *p = &c;

    b = *p;     // *pb = *p
	int a = 0;
009925F2  mov         dword ptr [a],0		; *(&a) = 0
	int& b = a;
009925F9  lea         eax,[a]  				; eax = &a
009925FC  mov         dword ptr [b],eax  	; *(&b) = &a,实际上 b 就是一个指针变量,里面保存的是 a 的地址。

	int c = 4;
009925FF  mov         dword ptr [c],4  		; *(&c) = 4
	int* p = &c;
00992606  lea         eax,[c]  				; eax = &c
00992609  mov         dword ptr [p],eax  	; *(&p) = &c

	b = *p;
0099260C  mov         eax,dword ptr [b]  	; eax = *(&b), *(&b) == &a,变量 a 的地址赋值给了 eax 。
0099260F  mov         ecx,dword ptr [p]  	; ecx = *(&p), *(&p) == &c,变量 c 的地址赋值给了 ecx 。
00992612  mov         edx,dword ptr [ecx]  	; edx = *(&c),变量 c 的值赋值给了 edx 。
00992614  mov         dword ptr [eax],edx 	; *(&a) = *(&c),变量 c 的值赋值给了变量 a 。

三、其他

汇编代码作用
[a]取变量 a 的地址,即:&a
dword ptr [a]获取变量 a 的值,即:在内存的 a 的地址的位置获取双字大小的数据,即:*(&a) 。
dword ptr [ecx]在内存中 ecx 中的值所代表的地址上的双字大小的数据,即:*ecx 。

 

(SAW:Game Over!)

修正下述代码的销毁字体纹理部分 //库 #include "imgui.h" #include "imgui_impl_opengl3.h" #include <GLES3/gl3.h> #include <android/log.h> #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, "ImGui", __VA_ARGS__) // 静态数据 static const char* g_GlslVersion = nullptr; static GLuint g_FontTexture = 0; static int g_ShaderHandle = 0; static GLuint g_VertexArrayHandle = 0; static GLuint g_VertexBufferHandle = 0; static GLuint g_IndexBufferHandle = 0; static int g_LocationTex = 0; static int g_LocationProjMtx = 0; static int g_LocationPosition = 0; static int g_LocationUV = 0; static int g_LocationColor = 0; //..-----------------------------分割线---------------------- // 销毁字体纹理 void ImGui_ImplOpenGL3_DestroyFontsTexture() { if (g_FontTexture != 0) { ImGuiIO& io = ImGui::GetIO(); io.Fonts->TexID = 0; glDeleteTextures(1, &g_FontTexture); g_FontTexture = 0; } } 错误报告: D:\Users\Administrator\AppData\Local\sdk\ndk\25.1.8937393\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe --target=x86_64-none-linux-android26 --sysroot=D:/Users/Administrator/AppData/Local/sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/windows-x86_64/sysroot -Dnative_lib_EXPORTS -IG:/Users/Administrator/AndroidStudioProjects/PoBeWorld/app/src/main/cpp/imgui -IG:/Users/Administrator/AndroidStudioProjects/PoBeWorld/app/src/main/cpp -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -std=c++17 -fno-limit-debug-info -fPIC -MD -MT CMakeFiles/native-lib.dir/imgui_impl_opengl3.cpp.o -MF CMakeFiles\native-lib.dir\imgui_impl_opengl3.cpp.o.d -o CMakeFiles/native-lib.dir/imgui_impl_opengl3.cpp.o -c G:/Users/Administrator/AndroidStudioProjects/PoBeWorld/app/src/main/cpp/imgui_impl_opengl3.cpp G:/Users/Administrator/AndroidStudioProjects/PoBeWorld/app/src/main/cpp/imgui_impl_opengl3.cpp:295:25: error: use of overloaded operator '=' is ambiguous (with operand types 'ImTextureRef' and 'int') io.Fonts->TexID = 0; ~~~~~~~~~~~~~~~ ^ ~ G:/Users/Administrator/AndroidStudioProjects/PoBeWorld/app/src/main/cpp/imgui/imgui.h:357:8: note: candidate function (the implicit copy assignment operator) struct ImTextureRef ^ G:/Users/Administrator/AndroidStudioProjects/PoBeWorld/app/src/main/cpp/imgui/imgui.h:357:8: note: candidate function (the implicit move assignment operator) Ask Gemini D:\Users\Administrator\AppData\Local\sdk\ndk\25.1.8937393\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe --target=x86_64-none-linux-android26 --sysroot=D:/Users/Administrator/AppData/Local/sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/windows-x86_64/sysroot -Dnative_lib_EXPORTS -IG:/Users/Administrator/AndroidStudioProjects/PoBeWorld/app/src/main/cpp/imgui -IG:/Users/Administrator/AndroidStudioProjects/PoBeWorld/app/src/main/cpp -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -std=c++17 -fno-limit-debug-info -fPIC -MD -MT CMakeFiles/native-lib.dir/imgui_impl_opengl3.cpp.o -MF CMakeFiles\native-lib.dir\imgui_impl_opengl3.cpp.o.d -o CMakeFiles/native-lib.dir/imgui_impl_opengl3.cpp.o -c G:/Users/Administrator/AndroidStudioProjects/PoBeWorld/app/src/main/cpp/imgui_impl_opengl3.cpp G:/Users/Administrator/AndroidStudioProjects/PoBeWorld/app/src/main/cpp/imgui_impl_opengl3.cpp:295:25: error: use of overloaded operator '=' is ambiguous (with operand types 'ImTextureRef' and 'int') io.Fonts->TexID = 0; ~~~~~~~~~~~~~~~ ^ ~ G:/Users/Administrator/AndroidStudioProjects/PoBeWorld/app/src/main/cpp/imgui/imgui.h:357:8: note: candidate function (the implicit copy assignment operator) struct ImTextureRef ^ G:/Users/Administrator/AndroidStudioProjects/PoBeWorld/app/src/main/cpp/imgui/imgui.h:357:8: note: candidate function (the implicit move assignment operator) Ask Gemini
08-29
### 在 `B.h` 头文件中调用 `A.cpp` 函数的方法 在 C++ 中,头文件(`.h`)主要用于声明,而源文件(`.cpp`)用于定义实现。若需在 `B.h` 中调用 `A.cpp` 的函数,需通过以下标准化步骤实现: #### 📝 标准解决方案(推荐) ```cpp // 步骤 1: 在 A.h 中声明函数 // A.h #pragma once void functionInA(); // 函数声明 ``` ```cpp // 步骤 2: 在 A.cpp 中实现函数 // A.cpp #include "A.h" void functionInA() { // 函数具体实现 } ``` ```cpp // 步骤 3: 在 B.h 中包含 A.h 并调用函数 // B.h #pragma once #include "A.h" // 引入声明 inline void callFunctionInB() { functionInA(); // 通过内联函数调用 } ``` #### ⚠️ 关键技术要点 1. **声明与定义分离** - 头文件 `A.h` 仅包含函数**声明**(`void functionInA();`) - 源文件 `A.cpp` 包含函数**定义**(实现代码) - 这是 C++ 模块化的核心原则 2. **头文件保护机制** 使用 `#pragma once` 或传统宏防止重复包含: ```cpp #ifndef A_H #define A_H void functionInA(); #endif ``` 3. **调用方式选择** - **直接调用**:仅适用于头文件中的 `inline` 函数或模板 - **间接调用**:在 `B.cpp` 中实现调用更安全 4. **链接确保** 编译时需将 `A.cpp` 和 `B.cpp` 一起链接: ```bash g++ A.cpp B.cpp -o output ``` #### 🚫 避免常见错误 - **错误 1:在头文件中直接定义函数** ```cpp // ❌ B.h 错误示例 void callA() { functionInA(); // 未声明直接调用 } ``` **问题**:导致链接错误 `undefined reference` - **错误 2:省略声明文件** ```cpp // ❌ B.h 危险做法 extern void functionInA(); // 手动声明 ``` **问题**:破坏封装性,维护困难 #### 🔧 特殊场景处理 **场景 1:调用类成员函数** ```cpp // A.h class ClassA { public: void memberFunc(); }; // B.h #include "A.h" inline void callMember() { ClassA obj; obj.memberFunc(); } ``` **场景 2:混合 C/C++ 编程** 若 `A.cpp` 是 C 语言实现: ```cpp // A.h #ifdef __cplusplus extern "C" { // C++ 编译器下使用 C 链接规则 #endif void functionInA(); #ifdef __cplusplus } #endif ``` #### 📊 最佳实践总结 | 操作 | 正确做法 | 错误做法 | |---------------------|-----------------------------|-----------------------| | 函数声明位置 | `A.h` 头文件 | 直接在 `B.h` 声明 | | 函数定义位置 | `A.cpp` 源文件 | 头文件中实现 | | 头文件包含 | `#include "A.h"` 在 `B.h` | 省略包含 | | 调用位置 | `inline` 函数或 `B.cpp` | 普通函数直接调用 | > 关键原则:**声明在头文件,实现在源文件,调用需显式包含**会不会出现重复包含问题?
最新发布
10-01
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值