AoiJays's Space.

C++ 入门笔记

2023/12/23

C++ 入门

[TOC]

内存分区

  • 代码区
  • 全局区:全局变量 + 静态变量
  • 栈区:参数值、局部变量,由编译器自动分配释放
  • 堆区:程序员进行分配、释放,程序结束由操作系统收回
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
using namespace std;

const int x = 1;
int glo = 2;

int main() {

static int sta = 3;
const int y = 2;

cout << &x << "\n";
cout << &glo << "\n";
cout << &sta << "\n";
cout << &y << "\n";
}

// 0x55a18d36d004
// 0x55a18d36f010
// 0x55a18d36f014
// 0x7fff1260df64 局部常量是栈区

常量修饰

常量引用

1
2
3
4
5
6
7
// 禁止通过ref修改值
// 引用常量
const int & ref = temp;

// 理论上不存在引用常量
// 引用本质上是指针常量
int & const y = x;

常量指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int x = 2, y = 3;
const int * p = &x;

// 正确 不能通过常量指针修改值
// 但是你可以修改常量指针的指向
p = &y;

int * const p = &y;

// 正确 指针常量可以修改
*p = 3;
// 错误 常量的是指针本身
p = &y;

常量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const int z = 3;
// 常量的指针
int const * p = &z;
// 常量的引用
int const & v = z;



const int z = 3;
const int k = 5;

// 错误 p为指向常量的 常量指针
// 但是常量本身就不能修改
// 限定指针不能修改常量没有意义
const int const * p = &z;

// 指向常量的指针常量
// 不可修改指针指向
int const * const p = &z;

其他

函数重载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void fun(int & x) {
cout << "this is 1";

}

void fun(const int& x) {

cout << "this is 2";
}

int main() {

int x = 2;
fun(x); // 调用int & x

const int y = 2;
fun(y); // 调用 const int & y

fun(10); // 调用 const int & y
// 常量指针可以接受常量
}

struct唯一的不同是默认权限

  • struct 默认:public
  • class 默认: private
  • 封装、继承、多态

构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Student s; // 调用默认构函数
Student s("hcf",21);

// 使用匿名对象进行初始化
// 该行代码结束立马释放
Student s = Student("hcf",21);

// 有参构造函数
Student s2 = {"Souuma", 21};

// 若提供以下构造函数:
Student(int age) : age(age) {
this->user_name = "Null";
}
// 则可以 :
Student s3 = 10;


Student s(); // 声明一个返回值为Student的函数s

拷贝构造函数

1
2
3
Student( const Student & s) {

}
1
2
3
4
5
6
7
   Student s1("Uchyama",21);
s1.ShowStudent();


// 错误 匿名对象不能单独使用拷贝构造函数
// 会被编译成:Student s1; 与前面重复定义
Student(s1);

调用途径:

  • Student s1(s2);
  • Student s2 = Student(s1);
  • Student s3 = s2;

使用场景:

  • 初始化新对象

  • 值传递:函数参数传值

    • ```cpp
      void test( Student s ) {

      }

      int main() {

      Student temp;
      test( temp );
      

      }
      // 输出:
      // 无参构造函数!
      // 拷贝构造函数!
      // 析构函数!
      // 析构函数!

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21

      -

      - 值返回:函数返回局部对象

      - ```cpp

      Student test() {
      Student temp; // 调用无参构造函数
      return temp;
      }

      int main() {

      Student temp = test();
      // temp的析构函数
      }
      // 但是现在的编译器会把这里给优化掉
      // 所以输出:
      // 无参构造函数!
      // 析构函数!
深拷贝与浅拷贝
  • 浅拷贝:拷贝值

    • 对象A含有一指针p,B浅拷贝了A
    • A析构,A.p指向的内存被释放
    • B析构,B.p = A.p,执行的内存会被重复释放
  • 深拷贝:

    • 为B新建一个内存,B.p指向

    • 通过定义拷贝构造函数

    • ```cpp

          Student( const Student & student ) {
              this->m_age = student.m_age;
              this->height = new int( *student.height );
          }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44



      ### 析构函数

      - 不能重载,没有参数
      - 只会被调用一次





      ### 静态成员

      ```cpp
      class Student {

      public:

      // 只有常量才能才能在类内初始化
      static const int A = 0;
      static int B;

      static void fun() {
      ++B;
      }
      };

      int Student::B = 0;

      int main() {

      Student p;


      cout << Student::A << " " << Student::B << "\n";
      cout << p.A << " " << p.B << "\n";

      p.fun(); Student::fun();

      cout << Student::A << " " << Student::B << "\n";
      cout << p.A << " " << p.B << "\n";

      }
  • 静态成员函数只能访问静态成员

其他

空指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Student {
public:

static const int x = 2;
void fun() {
cout << "YES";
cout << x;
}
};

int main() {

Student *p = NULL;

p->fun();
cout << p->x << "\n";

}

空指针可以使用成员函数

但是无法使用成员变量,会直接出错

常函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int y = 1;
class Student {


public:

// 可被常函数修改
mutable int x ;

void fun() const {
x = 2; y = 3;
}
};

int main() {

Student p;

p.fun();

cout << p.x << " " << y;

}
CATALOG
  1. 1. C++ 入门
    1. 1.1. 内存分区
    2. 1.2. 常量修饰
      1. 1.2.1. 常量引用
      2. 1.2.2. 常量指针
      3. 1.2.3. 常量
    3. 1.3. 其他
      1. 1.3.1. 函数重载
    4. 1.4.
      1. 1.4.1. 构造函数
        1. 1.4.1.1. 拷贝构造函数
          1. 1.4.1.1.1. 深拷贝与浅拷贝
      2. 1.4.2. 其他
        1. 1.4.2.1. 空指针
        2. 1.4.2.2. 常函数