Loading...

C++基础

C++基础
  iwehdio的博客园:https://www.cnblogs.com/iwehdio/

1、C++基础

  • C++相对C语言增加了,面向对象的通用算法。
  • C标准库的C++移植:大部分C标准库的头文件 x.h 在C++中为 cx 。
  • 多行注释:/* */,单行注释://
  • 标准输入输出头文件:#include<iostream>
  • cout是标准输出流变量(对象),代表控制台窗口。<<是输出运算符。cin>>与之对应。endl换行。
  • 名字空间:解决命名冲突问题。如名字空间 std 下的 cout 表示为:std::cout。也可以在程序开头声明整个名字空间:using namespace std;
  • 文件操作:#include<fstream>
    • 打开并写入文件:ofstream oF("文件路径");
    • 写入内容:oF<<写入内容;
    • 关闭文件:oF.close();
    • 打开并读取文件:ifstream iF("文件路径");
    • 读取内容:iF>>接收内容的变量;

2、C++函数

  • 引用变量:其他变量的别名。

    • 如:int a = 1; int &r = a;
    • 定义引用变量时就必须指明引用的是哪一个变量,且一旦定义就不能再引用其他变量。
    • 引用变量和被引用的变量类型必须匹配,对引用变量的操作就是对它引用的变量的操作。
  • 引用形参:

    • C函数是值参数,对形参的改变不会改变实参。

    • 如:

      void swap(int x, int y){
          int t = x;
          x = y;
          y = t;
      }
      int main(){
          int a = 3, b = 4;
          swap(a,b);
      }
      

      实际上,a 和 b 的值还是原来的3、4,没有发生交换。

    • C语言中为了改变实参,需要传递指针。

    • C++中使用引用实参表达,即函数定义为void swap(int &x, int &y),其他相对上述程序不变。

    • 同样的符号作为定义变量和运算符的含义不同。作为定义变量的*表示定义指针类型的变量,作为运算符的*表示获取该地址存储的内容。作为定义变量的&表示定义引用类型的变量,作为运算符的&表示取该变量的地址值。

  • 函数的默认形参:

    • 函数的形参可以有默认值:void func(char ch, int n = 1);
    • 默认形参必须在非默认形参的右边:int add(int y, int x = 1, int z = 3);
  • 函数重载:

    • C++允许作用域内有同名的函数,只要他们的形参不同。

    • 函数名和形参列表构造了函数的签名。

    • 不能根据返回类型区分。

  • 函数模板:

    • 将数据类型泛型化,编写通用算法。

    • template关键字增加一个模板头,将数据类型变成类模板参数。

    • 使用时传入实际所需的模板参数进行实例化。

    • 如:

      template<typename T>
      T add(T x, T y){
          return x + y;
      }
      //传递实际的模板参数 int 
      cout << add<int>(5, 3);
      

3、string和vector

  • string :是一个用户定义类型,表示的是字符串。

    • 定义:string s = "hello";
    • 用成员运算符 . 访问 string 类的成员:
      • .size():字符串大小。
      • .substr(f, e):从原字符串中获取索引从 f 到 e 的子串。
      • +:字符串拼接。
      • s[x]:获取或赋值索引为 x 的值。
      • .find(子串):获取子串在原字符串中的位置。
      • .insert(index, 子串):在 索引为 index 的位置插入子串。
  • vector :向量,类似于数组,但可以动态生长。

    • 头文件:#include<vector>

    • 是一个类模板,实例化产生一个类。如vector<int> v = {1,2,3,4};

    • v.push_bach(element);:在最后添加一个元素。

    • v.size();:向量大小。

    • v.pop_back();:弹出最后一个元素。

    • v.resize(size);:重新定义大小,留下前 size 个元素。

4、指针和动态内存分配

  • 指针:指针就是地址,变量的指针就是变量的地址。可以用取地址运算符&获得一个变量的地址。

  • 指针变量:存储指针(地址)的变量。T *p表示 p 是存储 T类型变量的地址 的变量。

  • 通过取内容运算符*可以得到一个指针指向的变量。*p就是p指向的变量。

    • 如:

      int a = 3;
      int *p = &a;
      /* 此时,p == &a
              *p == a
      */
      
      int *q = p;
      // 此时,*p == *q == a
      
  • 申请 n 个 int 大小的内存:int *p = new int[n];

  • 释放内存:delete p;,否则会出现内存泄漏。如果是数组则delete[] p;

5、 类和对象

程序是由不同种类的许多对象相互协作完成。有哪些对象?对象有什么类型?对象直接有什么关系?

  • C++中如何定义一个类: struct 或 class 关键字。( struct 中的成员默认 public ,class 中的成员默认 private )

    class student {
        public: string name;
        public: double score;
        public: void print(){
            cout<<name<<score;
        }
    };
    student stu;		//实例化对象
    stu.name = "A";		//赋值
    stu.score = 78;	
    
  • 类类型的指针变量:T 是一个类类型,则 T * 就是 T 指针类型。T * 变量可以指向一个类对象。

    student stu;
    student *p = &stu;
    //两种访问成员的方法:
    (*p).name = "B";	//取内容运算符*
    p->score = "C";		//间接访问运算符->
    
  • 指向动态分布的对象。

    student *p = new student;
    p->name = "D";
    delete p;
    
  • 类体外也可以定义成员函数,但要声明作用域 void student::print(){}

  • this 指针:指向调用成员方法的对象。

  • 一般成员变量为设置为 private ,通过 get 和 set 函数获取和修改。

  • 构造函数:创建对象时自动调用的,函数名和类名相同且没有返回类型的函数。默认构造函数为 student(){}。如果自定义了构造函数,则不再自动生成默认构造函数。

6、重载

  • 运算符重载:

    • cout << 实际上的完整函数名是:operator<<()
    ostream& operator<<(ostream &o, student s){
        cout << s.name << s.score;
        return o;
    }
    cout << stu;
    
    • cin >> 同理,除了为了修改student 的成员变量,输入应用引用。
    istream& operator>>(istream &in, student &s){
        cin >> s.name >> s.score;
        return in;
    }
    cin >> stu;
    
  • friend 关键字:外部函数无法访问类的私有成员,可以用 friend 关键字声明该函数是类的友元函数。

    friend ostream& operator<<(ostream &o, student s);
    
  • 下标运算符必须在类中重载,即成员方法:

    class point {
    public: 
        double x, y;
        //用下标获取数据
        double operator[](int n) const {	//常函数,不会对成员变量进行修改
            if(n == 0){
                return x;
            } else {
                return y;
            }
        }
        //用下标更改数据需要返回引用,通过 const 关键字重载
        double& operator[](int n){	
            if(n == 0){
                return x;
            } else {
                return y;
            }
        }
    }
    
  • 拷贝构造函数:用一个对象赋值给另一个对象。

    • 没有定义会自动生成默认拷贝构造函数,执行硬拷贝。

      class String {
          char *data;
          int n;
      public:
          String(const String &s){
              data = s.data;
              n = s.n;
          } 
      }
      
    • 硬拷贝会导致两个对象指向同一块内存,改变其中一个,另一个也会随之改变。

    • 对于引用数据类型的成员变量,需要重写拷贝构造函数:

      String(const String &s){
          data = new char[s.n + 1];
          n = s.n;
          for(int i=0;i<n;i++)
              data[i] = s.data[i];
          data[n] = '\0';
      } 
      
  • 析构函数:在函数执行完后释放内存。

    • 不带参数也没有返回类型。

    • 默认析构函数:~String(){}

    • 有引用数据类型的,用 delete 释放内存。

      ~String(){
          if(data)
          	delete[] data;
      }
      

iwehdio的博客园:https://www.cnblogs.com/iwehdio/
posted @ 2020-01-31 18:08  iwehdio  阅读(129)  评论(0编辑  收藏  举报