主要使用软件为 QtCreator

1. 创建项目

image-20201210161955763

工程名字,不能有空格,中文,特殊字符

image-20201210162339510

2. QT编译注意事项

image-20201210162724478

image-20201210162824318

输出结果在编辑器本地

image-20201210180059683

Run in terminal。

在Windows下中文输出默认是乱码,默认编码是UTF-8,需要调整(存疑,需要验证)

3. C++ 基本

Helloword

// i input 输入 o output 输出 steam 流
#include <iostream>
// std 标准 标准命名空间
using namespace std;
// 有且仅有一个主函数
int main() {
    // endl 换行符

    // cout 代表输出设备
    cout << "Hello !" << endl;

    // cin 代表输入设备
    int num = 0;
    cin >> num;
    // 目的是写代码
    // 将键盘输入的数字复值给number
    cout << "num = " << num << endl;

    return 0;
}

头文件风格

image-20201210181953389

注意

  1. C++系统头文件风格iostreamc语言的头文件比如string.hc++工程可以写成string.h或者cstring

  2. C语言是弱语法语言(很多警告 可以忽略 正常运行),C++强语法语言(很多C语言的警告在C++中直接报错;

  3. C面向过程:面向过程编程思想的核心:功能分解,自顶向下,逐层细化(程序=数据结构+算法。)

    1. 数据结构:就是对数据的存储方式(指的是数据类型:char short int long float struct unions 数组 链表等等)
    2. 算法: 就是对存储好的数据 进行分析的步骤(操作数据的步骤 == 功能函数
  4. 面向对象编程:在面向对象中,算法与数据结构被看作是一个整体,称作对象。

    对象 = 算法 + 数据结构

    程序 = 对象 + 对象 + 对象 + ……

4. C++的三大特性

  • 封装:把客观事物封装成抽象的类(将数据和方法打包在一起,加以权限的区分,达到安全使用数据的目的)

  • 继承:表达类之间的关系,这种关系使得对象可以继承另外一类对象的特征和能力

    • 目的:避免公用代码重复开发,减少代码和数据冗余
  • 多态:一个接口,多种方法。字面意思是多种形态。程序在运行时才决定调用的函数,它是面向对象编程领域的核心概念。 (存疑)

5. C++C的扩展

5.1 ::作用域运算符

#include <iostream>

using namespace std;
int a = 10; // 全局变量
void test01() {
  int a = 20; // 局部变量
  cout << "a = " << a << endl; // 优先选择局部变量

  // :: 作用域运算符 (C++ 独有)
  cout << "全局变量 a " << ::a << endl;
}

int main()
{
  test01();
//  cout << "Hello World!" << endl;
  return 0;
}

5.2 命名空间

名字控制,c语言可以通过static关键字使得名字只在本编译单元可见,在C++中通过命名空间来控制对名字的访问。

// 定义一个名字为A的命名空间(变量、函数)
namespace A {
  int a = 100;
}
namespace B {
  int a = 200;
}

void test02() {
  // A::a a 是属于A中
  cout << "A 中 a = " << A::a << endl;
  // B::a a 是属于B中
  cout << "B 中 b = " << B::a << endl;
}
  1. 命名空间只能在全局范围内定义

  2. 命名空间可以嵌套

  3. 命名空间是开放的,可以随时添加新的成员

  4. 命名空间可以存放变量和函数

  5. 命名空间可以存放变量和函数

    namespace A {
      int a;
      void func() {
        cout << "func遍历a = " << a << endl;
      }
    }
    
    void test05() {
      // 变量使用
      cout << "A 中的a = " << A::a << endl;
    
      // 函数调用
      A::func();
    }
  6. 命名空间中的函数 可以在外边定义

    namespace A {
      int a = 100;
      void func();
    }
    
    void func() { // 普通函数
      cout << endl;
    }
    
    void A::func() { // 成员函数
      cout << "命名空间外部定义的函数" << endl;
    }
    
    void test06() {
        A::func();
    }
  7. 无名的命名空间,意味着命名空间中的标识符只能在本文件内访问,相当于给这个标识符加上了static,使得其可以作为内部连接(不会这么写)

  8. 命名空间别名

    namespace veryLongName {}
    void test() {
        namespace shortName = veryLongName;
    }

5.3 using声明

using使用命名空间

namespace veryLongName {
  int a = 100;
  void func() {
    cout << "veryLongName namespace" << endl;
  }
}

void test07() {
  int b = 1000;
  // 使用veryLongName命空间
  using namespace veryLongName;

  // 出现的变量 先从veryLongName 命名中间中找, 找不到 其他地方找
  cout << "a = " << b << endl;
  func();
}
  1. 简化了命名空间的成员访问

  2. 代价:容易冲突

    namespace veryLongName {
        int a = 100;
        int b = 20000;
        void func() {
            cout << "veryLongName namespace" << endl;
        }
    }
    
    void test07() {
        int a = 200;
        int b = 1000;
        // 使用veryLongName命空间
        using namespace veryLongName;
    
        // 出现的变量 先从veryLongName 命名中间中找(这里存疑, 找不到 其他地方找
        cout << "a = " << a << endl // 获取局部变量
             << "b = " << b << endl;
        cout << veryLongName::a << endl; // 解决 冲突
        func();
    }
  3. using使用具体的命名空间成员

    namespace veryLongName {
        int a = 100;
        int b = 20000;
        void func() {
            cout << "veryLongName namespace" << endl;
        }
    }
    
    namespace A {
       int a = 200;
    }
    
    namespace B {
       int a = 300;
    }
    
    namespace C {
       int a = 400;
    }
    
    void test08() {
        using namespace veryLongName;
        using namespace A;
        using namespace B;
        using namespace C;
    
        cout << a << endl; // 命名冲突, 
    }
    
    //void test07() {
    //    int a = 200;
    ////    int b = 1000;
    ////    // 使用veryLongName命空间
    //////    using namespace veryLongName;
    
    ////    // 出现的变量 先从veryLongName 命名中间中找(这里存疑, 找不到 其他地方找
    ////    cout << "a = " << a << endl // 获取局部变量
    ////         << "b = " << b << endl;
    
    //    cout << veryLongName::a << endl; // 解决 冲突
    
    ////    using veryLongName::a; // 如果同名 会冲突
    //    // 冲突 namespace 会使用哪个辩量呢? 优先使用 局部变量, 如果局部变量没有呢?
    //    cout << a << endl;
    
    ////    func();
    //}

    *要注意自己在做什么, 为了安全一般直接使用 namespace::val *

    不会和全局作用域冲突 using namespace::val ::val

  4. using在函数重载下的应用

    namespace A {
        void func() {cout << "void" << endl;}
        void func(int a) {cout << a << " a func" << endl;}
        void func(int a, int b) {cout << a << b << " a b func" << endl;}
    }
    
    void test08() {
        // using 指明 使用 A 中的func会使用所有func起作用
        using A::func;
    
        func();
        func(1);
        func(1, 2);
    }

    对所有函数都会其作用 (作用)

  5. 二义性问题

    namespace A {
       int a = 0;
    }
    
    namespace B {
        int a = 1;
    }
    
    namespace C {
        int a = 2;
    }
    
    void test09() {
        int a = 3;
        using namespace A;
        using namespace B;
        using namespace C;
    
        // 局部变量拥有则不会弹出二义性警告,优先使用局部变量!
        cout << a << endl;
    }
    
    // 如果局部变量不存在,就会不清楚究竟访问哪个变量,存在二义性

5.4 命名空间总结

  1. 命名空间的定义(不能在函数内 定义命名空间)
  2. 使用命名空间的成员 最安全的方式 命名空间名::成员名
  3. using namespace 命名空间名;使用整个命名空间
  4. 单独 使用命名空间中的具体成员 using 命名空间名::成员名

总结与注意点

image-20201210210034196

三大特性:封装、继承、多态