C++学习总结
环境:Linux
多个头文件定义同一个namespace
存在两种情况:
- 名字空间名称相同,成员名字不同(其中成员名字指的是命名空间中的类,函数以及变量),那么他们会自动合并为一个名字空间,可以理解为追加
- 名字空间名称相同,成员名称相同。那么程序会在调试过程的link时报错。因为连接器会检测到重复定义的变量
system()函数
命令行执行system内的命令
system("ls") // 命令行执行ls
C++中#和##的含义
C++中的#
和##
常用在宏定义中
- #是“字符串化”的意思,出想在宏定义中的#是将跟在后面的参数转换成一个字符串
- ##是一个连接符号,用于将参数连接到一起
```C++ #includeusing namespace std; #define F1(x,y) x##y #define F2(x) #x #define F3(x) cout<<"C"#x#x<<endl
int main() { int len = 0; F1(l, en) = 1; // 相当于将len重新赋值为1 cout « len « endl; // 输出1 cout « F2(sdf) « endl; // 输出sdf F3(p); // 输出Cpp return 0; }
## #progma once
为了避免同一个头文件被包含(include)多次,C/C++中有两种宏实现方式:
1. 一种是#ifndef方式
```C++
#ifndef __SOMEFILE_H_
#define __SOMEFILE_H_
... ... // 声明语句
#endif
- #ifndef的方式受C/C++语言标准支持。它不仅可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件(或者代码片段)不会被不小心同时包含。
- 当然,缺点就是如果不同头文件中的宏名不小心“撞车”,可能就会导致你看到头文件明明存在,但编译器却硬说找不到声明的状况——这种情况有时非常让人郁闷。
- 由于编译器每次都需要打开头文件才能判定是否有重复定义,因此在编译大型项目时,ifndef会使得编译时间相对较长,因此一些编译器逐渐开始支持#pragma once的方式。
- 一种是#pragma once方式
#pragma once
- #pragma once 一般由编译器提供保证:同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。
- 你无法对一个头文件中的一段代码作pragma once声明,而只能针对文件。
- 其好处是,你不必再担心宏名冲突了,当然也就不会出现宏名冲突引发的奇怪问题。大型项目的编译速度也因此提高了一些。
- 对应的缺点就是如果某个头文件有多份拷贝,本方法不能保证他们不被重复包含。当然,相比宏名冲突引发的“找不到声明”的问题,这种重复包含很容易被发现并修正。 另外,这种方式不支持跨平台!
- 一种是#pragma once方式
c++中的 . 和 .. 和 ->
- A.B则A为对象或者结构体
- A->B则A为指针,->是成员提取,A->B是提取A中的成员B,A只能是指向类、结构、联合的指针
- ::是作用域运算符,A::B表示作用域A中的名称B,A可以是名字空间、类、结构
- :一般用来表示继承
using关键字
- 对命名空间的using指令及对命名空间成员的using声明,eg:
using namespace std;
- 对类成员的 using 声明,eg:
using std::cout;
- 类型别名与别名模板声明(类似typdef), 详情见这里
typdef unsigned char u1; using u2 = unsigned short;
多态
通过指针调用普通的成员函数时会根据指针的类型(通过哪个类定义的指针)来判断调用哪个类的成员函数,但是通过本节的分析可以发现,这种说法并不适用于虚函数,虚函数是根据指针的指向来调用的,指针指向哪个类的对象就调用哪个类的虚函数。
c++11中for循环的新用法
#include<algorithm> // for for_each()
#include<iostream>
#include<vector>
using namespace std;
void func(int n)
{
cout << n << " ";
}
int main()
{
vector<int> arr = {1,2,3,4};
cout << "使用iterater遍历: ";
for (vector<int>::iterator it = arr.begin(); it != arr.end(); it++)
cout << *it << " ";
cout << "\n使用for_each()遍历: ";
for_each(arr.begin(), arr.end(), func);
// for_each(arr.begin(), arr.end(), &func); // 效果相同,为什么
cout << "\n使用c++11新特性:遍历: ";
for (int n : arr)
cout << n << " ";
cout << endl;
return 0;
}
/* 输出如下:
使用iterater遍历: 1 2 3 4
使用for_each()遍历: 1 2 3 4
使用c++11新特性:遍历: 1 2 3 4
*/