程序猿的自我修养 Weilit

C++学习笔记

2019-10-29

C++学习总结

环境:Linux

多个头文件定义同一个namespace

存在两种情况:

  1. 名字空间名称相同,成员名字不同(其中成员名字指的是命名空间中的类,函数以及变量),那么他们会自动合并为一个名字空间,可以理解为追加
  2. 名字空间名称相同,成员名称相同。那么程序会在调试过程的link时报错。因为连接器会检测到重复定义的变量

system()函数

命令行执行system内的命令

system("ls")    // 命令行执行ls

C++中#和##的含义

C++中的###常用在宏定义中

  1. #是“字符串化”的意思,出想在宏定义中的#是将跟在后面的参数转换成一个字符串
  2. ##是一个连接符号,用于将参数连接到一起
    ```C++ #include using 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的方式。
    1. 一种是#pragma once方式
      #pragma once
      
      • #pragma once 一般由编译器提供保证:同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。
      • 你无法对一个头文件中的一段代码作pragma once声明,而只能针对文件。
      • 其好处是,你不必再担心宏名冲突了,当然也就不会出现宏名冲突引发的奇怪问题。大型项目的编译速度也因此提高了一些。
      • 对应的缺点就是如果某个头文件有多份拷贝,本方法不能保证他们不被重复包含。当然,相比宏名冲突引发的“找不到声明”的问题,这种重复包含很容易被发现并修正。  另外,这种方式不支持跨平台!

c++中的 . 和 .. 和 ->

  1. A.B则A为对象或者结构体
  2. A->B则A为指针,->是成员提取,A->B是提取A中的成员B,A只能是指向类、结构、联合的指针
  3. ::是作用域运算符,A::B表示作用域A中的名称B,A可以是名字空间、类、结构
  4. :一般用来表示继承

using关键字

  1. 对命名空间的using指令及对命名空间成员的using声明,eg: using namespace std;
  2. 对类成员的 using 声明,eg: using std::cout;
  3. 类型别名与别名模板声明(类似typdef), 详情见这里
     typdef unsigned char u1;
     using u2 = unsigned short;
    

多态

参考:C++多态和虚函数快速入门教程
C++函数编译原理和成员函数的实现

通过指针调用普通的成员函数时会根据指针的类型(通过哪个类定义的指针)来判断调用哪个类的成员函数,但是通过本节的分析可以发现,这种说法并不适用于虚函数,虚函数是根据指针的指向来调用的,指针指向哪个类的对象就调用哪个类的虚函数。

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 
*/

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

¥ 打赏博主

类似文章

下一篇 CMake相关

留言