c++基础

一、基础知识:

1.构造和析构

类的构造函数是一种特殊的函数,在创建一个新的对象时调用。类的析构函数也是一种特殊的函数,在删除所创建的对象时调用。

构造顺序:父类->子类

析构顺序:子类->父类

2.函数重载和运算符重载
  • 函数重载:在同一作用域内可以声明多个重名函数,其函数参数的个数或顺序或类型必须不同,不能仅通过返回类型的不同来重载函数。

  • 运算符重载:运算符重载函数是类的成员函数(法一)时,它的第一个操作数是调用该函数的对象(即 this 指针指向的对象),第二个操作数是通过参数传递的对象。

Box operator+(const Box& b) {
    Box box;
    box.length = this->length + b.length;
    box.breadth = this->breadth + b.breadth;
    box.height = this->height + b.height;
    return box;
}

上述代码是针对+的重载,可以实现两个Box对象的相加。

还有一种方式是通过全局函数的方式重载(定义在类外面)

Box operator+(const Box& a, const Box& b) {
    Box box;
    box.setLength(a.getLength() + b.getLength());
    box.setBreadth(a.getBreadth() + b.getBreadth());
    box.setHeight(a.getHeight() + b.getHeight());
    return box;
}

调用方式依然是Box3=Box1+Box2。此时编译器会将其解释为Box3 = operator+(Box1, Box2);

3.结构体内存对齐
含义:以空间换时间,使一次访存可以取出一条指令,加快存取速度,常用于RISC指令流水线。

//  可查看struct大小
struct Example {
  char a;      // 1 字节
  int b;       // 4 字节
  double c;    // 8 字节
};
cout << "Size of Example: " << sizeof(Example) << endl;

如何控制内存对齐方式?

1.c++11提供了alignas,可以指定结构体对齐方式。
struct alignas(16) Example {
    char a;
    int b;
    double c;
};

注意事项:alignas的对齐值必须是2的幂次倍,且不能小于结构体最小成员对齐值。

当指定数值小于默认值的时候,alignas无效。

2.#pragma pack(push,n)
  alignas无效时,使用#pragma强制将对齐方式设置为 n 字节

二、指针和引用

1.指针
  • 指针是一个变量,存储的是另一个变量的内存地址
  • 指针可以指向任意类型的对象,包括空指针
  • 指针可以在任何时候被重新赋值
  • 在定义中使用 * 声明指针,使用&获取地址。
  int a = 10;
  int* p = &a;
  std::cout << "p=" << p << " *p=" << *p << "\n";
  输出结果为p=BAF0DDF750 *p=10
  p是指针,存的是所指变量的地址,*p获取所指变量的值
2.引用
  • 使用 & 声明引用,绑定后不能更换
  • 引用直接访问绑定的变量,无需解引用
  • 引用是一个变量的别名,在定义时必须初始化
  • 引用不可以为空,必须绑定到一个有效对象
int a = 10,b=20;
int& ref = a;  // ref绑定到a,ref 是 a 的别名
// int& ref2;  // 错误:引用必须初始化
// ref = b;    // 这不是重新绑定,而是将 b 的值赋给 a
3.指针和变量的区别
  • 指针是一个独立的变量,占用内存。引用占不占内存需要看编译器
  • 指针有多级指针,引用只有一级。
  int a = 10;
  int* p1 = &a;// p1指向a
  int** p2 = &p1;//p2指向p1
  int &ref=a;
  cout << "p1=" << p1 << " *p1=" << *p1;//p1存储a的地址,*p1获取a的值
  cout << "p2=" << p2 << " *p2=" << *p2 ;p2存储p1的地址,*p2获取p1的值
  运行结果 
  p1=0000009BADFDF7E8 *p1=10
  p2=0000009BADFDF7E0 *p2=0000009BADFDF7E8
  • sizeof(p1)=8,获取的是p1这个指针的大小。sizeof(ref)=4,获取的是a的大小。
  • 当把指针作为参数进行传递时,也是将实参的一个拷贝传递给形参,两者指向的地址相同,但二者是独立变量,在函数中改变这个变量的指向不影响实参。而引用却可以,函数接收的是原变量的引用(别名),操作引用等同于操作原变量。

需要注意的小地方

  • *的两种用途:在声明中用于表示指针类型。表达式中用于解引用指针,访问指针指向的值
  • &的两种用途:在引用声明中使用,定义一个引用(别名)。在指针声明中使用,获取变量的内存地址

三、堆和栈

在这里插入图片描述

  • 堆(Heap):用于运行时的动态内存分配,向上(高地址)生长。代码和数据区,在进程开始运行时就被指定了大小;而通过调用 malloc 和 free 这样的 C 标准库函数,可以让堆区动态地扩展和收缩。

  • 用户栈(Stack):位于虚拟地址空间用户区顶部,向下(低地址)生长。一般用来存储局部变量和函数参数,结合堆栈指针可以方便地实现函数的调用和返回。

  • 区别

  • 申请方式不同:栈由系统自动分配。堆是自己申请和释放的。

  • 申请效率不同:
    栈由系统分配,速度快,不会有碎片。
    堆由程序员分配,速度慢,且会有碎片。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值