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. 常函数