前面其实欠了很多帐,好多次规划要写一些总结类似的博客,每次都是因为工作原因(ps:这个理由找的好鄙视一下自己)哈哈就耽搁了,这次一定不要了,先把C++ 语言篇总结完,在把前面一些需要提前补上的整理一下吧。真的是眼过千遍不如手过一遍,而且看了好多遍没有实际运用也很快就忘记了。
序
C++11之后的语言特性很贴合各种实践应用了,而我呢每次都不太会用,有时候看过好多次也知道有一个什么可以运用到项目上,又感觉到自己可能不能熟练应用就放弃了,之前很多次就因为强制转换不太理解C++11开始的强制转换的意图,所以只好用使用C风格的强制转换,而C++和C已经有了很多不同的地方了,很多强制转换已经不能使用简单的C风格的强制转换来完成了,就需要用到C++11更加合理安全的强制转换了。不要以为我要从强制转换说起,我还是参考《C++ Prime》的目录的顺序来写吧。(PS:这也可能是这本书前400页比较旧的原因吧,这已经不知道是第几次从头看这本书了 23333333)
编译、运行
为什么说这个是因为Linux我不熟悉,正好可以温故一下Linux的编译吧。
编写好程序后,我们就需要编译它。如何编译程序依赖于你使用的操作系统和编译器。1
之前大多都是在继承开发环境(Integrated Developed Environment,IDE)上进行编译的,之前移植程序也是依靠QT的qmake来完成的。如何使用VS编译程序这里就不叙述了,我电脑是Mac,所以这里就来一次Mac上编译一个C++程序吧。
//不会用mac 创建文件哈哈,只好用vim
//开始写代码:
#include <iostream>
using namespace std;
int main()
{
cout<<"hello Mac!"<<endl;
return 0;
}
//使用命令行 编译、运行程序的语句:
g++ Compile_one_file_main.cpp
./a.out
多个文件的编译与链接:
文件:main.cpp
#include <iostream>
#include <Complex.hpp>
using namespace std;
int main()
{
Complex a(2,3);
cout<<"Complex a: real is "<<a.real_<<",imaginary is "<<a.imaginary_<<"."<<endl;
return 0;
}
文件:Complex.hpp
#ifndef COMPLEX_HPP
#define COMPLEX_HPP
class Complex
{
public:
Complex(int real,int imaginary);
~Complex()=default;
int real_;
int imaginary_;
};
#endif //! COMPLEX_HPP
文件:Complex.cpp
#include "Complex.hpp"
Complex::Complex(int real,int imaginary)
:real_(real)
,imaginary_(imaginary)
{}
其中目录结构为:
经过一番研究,就直接上编译过程吧。
先进入Complex.cpp目录。
MacBook-Pro:compile_multiple_file wtayu$ cd src/
由于Complex.cpp文件中没有main函数,编译器无法定义程序入口,所以无法生产可执行文件,先将Complex.cpp编译成*.o为文件。
MacBook-Pro:src wtayu$ g++ Complex.cpp
In file included from Complex.cpp:1:
./Complex.hpp:8:14: warning: defaulted function definitions are a C++11
extension [-Wc++11-extensions]
~Complex()=default;
^
1 warning generated.
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
MacBook-Pro:src wtayu$ g++ -c Complex.cpp
In file included from Complex.cpp:1:
./Complex.hpp:8:14: warning: defaulted function definitions are a C++11
extension [-Wc++11-extensions]
~Complex()=default;
^
1 warning generated.
MacBook-Pro:src wtayu$ ls
Complex.cpp Complex.hpp Complex.o
回到mian.cpp目录,编译mian.cpp 并告诉他附加目录的位置为src,且指定需要链接的中间文件,最后指定输出可执行程序名称。
MacBook-Pro:src wtayu$ cd ..
MacBook-Pro:compile_multiple_file wtayu$ g++ main.cpp -I src/ src/Complex.o -o main
In file included from main.cpp:2:
src/Complex.hpp:8:14: warning: defaulted function definitions are a C++11
extension [-Wc++11-extensions]
~Complex()=default;
^
1 warning generated.
MacBook-Pro:compile_multiple_file wtayu$
编译成功后运行可执行文件,查看打印结果。
MacBook-Pro:compile_multiple_file wtayu$ ./main
Complex a: real is 2,imaginary is 3.
如果看不懂这个编译过程可以参考简书博客:
《在linux下使用gcc/g++编译多个.h .c 文件》2
这个博客中还提到了extern这个关键词,所以我也顺便写了测试一下。我在src下新建文件:Extern_test.cpp,并写如下面代码:
int g_test = 10;
修改文件:main.cpp:
#include <iostream>
#include <Complex.hpp>
using namespace std;
extern int g_test;
int main()
{
Complex a(2,3);
cout<<"Complex a: real is "<<a.real_<<",imaginary is "<<a.imaginary_<<"."<<endl;
cout<<"Extern test value is: "<<g_test<<"."<<endl;
return 0;
}
然后分别编译,编译main.cpp时将新的Extern_test.o也链接上,终端代码如下:
g++ main.cpp -I src/ src/Complex.o -std=c++11 src/Extern_test.o -o main
这次我还加了C++11的编译选项,更多代码可以参考简书博客:
《GCC编译器选项解析》3
刻意颠倒了编译命令的顺序,发现链接时好想没有分先后顺序,只要全部链接上就可以了。这里可能不是太懂,大佬看到可以在下面留言分享一下。也抛出一个我能想象到的一个问题,当两个*.o文件都有符合main.cpp链接的定义时会如何选择呢?是链接失败呢还是会按一定规则去链接呢?
好了这里编译的部分就基本温故知新的差不多了。上面的测试代码我会上传到github上面,方便参考。(ps:这个测试的代码放在自己的电脑里千年不看一次,突然看到还想删,觉得占地方,传到github上面挺好的哈哈。)
ps:上面include头文件都是使用的<>,因为是在mac上编译,所以给一个linux下头文件寻找规则的博客链接:LINUX下默认搜索头文件及库文件的路径4