此前,一直做前端开发,对后端技术,抱着不求甚解的态度。今觉此态度,已演化成沉重的桎梏。故而预借源码,去揣摩学习。然而,大都项目的底层,以C/C++实现,想一点一滴重拾起,这尘封已久的记忆。
环境
系统:macOs Monterey
处理器:Intel Core i5
IDE:Xcode
在IDE选择上,网上搜了下,说Xcode是苹果系统集成IDE,适合开发苹果APP且功能强大。就想下载下来玩一下。记得上学那会儿,在Windows上,老师推荐用的是MinGW。工作之后,看大哥们使用Visual Studio进行开发。网上视频中,有人推荐使用Vscode,更有甚者使用Vim,Vi命令直接开撸。对于学习C++代码而言,重要的是对C++源代码的编译过程,先有一定的理解。目前主流编译器是gcc、clang,可以通过man gcc ,查看编译器提供的编译指令,了解这些指令背后的意义,更好的去完成C++代码的编译和优化。
项目介绍
- cplus_primer_01
- main.cpp
- MyClass.cpp
- MyClass.h
想要通过main函数,调用自定义类MyClass的Compute方法。
main.cpp
#include
#include "MyClass.h"
int main(int argc, const char * argv[]) {
// insert code here...
std::cout << "Hello, World!"<<std::endl;
MyClass my_class = MyClass();
std::cout << my_class.Compute(3, 5) << std::endl;
return 0;
}
MyClass.h
#ifndef MyClass_h
#define MyClass_h
class MyClass{
public:
MyClass();
int Compute(int a, int b);
};
#endif
MyClass.cpp
#include "MyClass.h"
int MyClass::Compute(int a, int b){
return a + b;
};
问题描述
哦豁,编译的时候,d出编译错误如下:
原因分析:
看字面意思是:在链接的时候,没有找到main.cpp中,MyClass的构造函数。(之前项目开发一直用C#,项目build过程,IDE一键完成。主要精力放在编译报错和业务调试环节。这次遇到这个提示挺有意思的)
网上查了一下,c++程序的编译经过以下几个环节:
1.预编译
- 将.cpp 文件转化成 .ii文件
- 使用的clang++命令是:clang++ –E
2.编译
- 将.ii 文件转换成.s文件
- 使用的clang++命令是:clang++ –S
3.汇编
- 将.s 文件转化成 .o文件
- 使用的clang++命令是:clang++ –c
4.链接
- 将.o 文件转化成可执行程序
- 使用的clang++ 命令是: clang++
man clang 查到有指令参数 -save-temps 可以将编译中间步骤产生的文件存储下来。
clang++ -save-temps main.cpp MyClass.cpp
ls -alF
查看预编译后生成的文件 main.ii
看到已经将MyClass.h的类声明给带入进来了!
看到预编译,已经将头文件类声明拷贝到此处。
说明不是头文件找不到,而是类定义的时候出了问题。
再看编译报错的原因,Undefined Symbols ,MyClass::MyClass() 未定义的标识。未定义?难道是对构造函数没有显示定义?因为印象里,构造函数是创建类的时候,编译器会帮我定义的。所以我只在头文件中,声明了一下,而在cpp文件里,没有对它实现。
解决方案:
在头文件中,去掉了构造函数的声明,编译通过。
MyClass.h
#ifndef MyClass_h
#define MyClass_h
class MyClass{
public:
int Compute(int a, int b);
};
#endif
总结
起初,由于对IDE和C++双重不熟,确定不了是编译配置的问题,还是代码链接的问题,走了不少弯路。现在看下来,其实编译器早就明确的告诉我错误的原因了。
写此文做为一个开始。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)