当前位置: 首页 > news >正文

C++11QT复习(二)

文章目录

    • Day4-4 New 与 delete 表达式(2025.03.20)
      • 1. `new` 表达式的三个步骤
      • 2. `delete` 表达式的两个步骤
      • 3. `new[]` 与 `delete[]`
    • Day5 类的定义和关键字再探(2025.03.24)
      • 1. C++ 关键字 `const`、`static`、`extern`
      • 2. 类的定义:Circle 和 Rect
      • 3. 完整代码
    • Day5-1 运算符重载(2025.03.24)
      • 1. 复数类 `Complex` 及其运算符重载
      • 2. 运算符重载的几种方式
      • 3. 关键区别
      • 4.完整代码

Day4-4 New 与 delete 表达式(2025.03.20)

在 C++ 中,newdelete 是用于动态内存管理的关键字。它们分别用于在堆上分配和释放对象或数组。

1. new 表达式的三个步骤

  1. 调用 operator new 标准库函数

    • operator new 负责在堆上申请一块原始的、未初始化的内存空间,以便存储对象。
    • 如果申请失败,会抛出 std::bad_alloc 异常(除非使用 nothrow 版本的 new)。
  2. 调用构造函数

    • 在申请到的内存空间上调用构造函数,初始化对象的数据成员。
  3. 返回指针

    • 返回指向新分配对象的指针,以供程序使用。

示例代码:

class A {
public:A() { cout << "A() constructor" << endl; }~A() { cout << "~A() destructor" << endl; }
};int main() {A* p = new A;  // 调用 operator new 申请内存 -> 调用构造函数 -> 返回指针delete p;      // 调用析构函数 -> 调用 operator delete 释放内存return 0;
}

2. delete 表达式的两个步骤

  1. 调用析构函数

    • 在释放对象所占的内存前,先执行析构函数,以回收对象的数据成员所占用的资源(如动态分配的内存、文件句柄等)。
  2. 调用 operator delete 库函数

    • 释放对象本身所占用的内存空间,使其可被重新分配。

示例代码:

A* p = new A;
delete p; // 先调用析构函数,再释放内存

3. new[]delete[]

  • new[] 用于动态分配对象数组,必须使用 delete[] 释放。
  • delete 只能释放单个对象,而 delete[] 释放的是整个数组。
A* arr = new A[5];  // 申请 5 个对象的数组delete[] arr;       // 释放数组

如果用 delete 释放 new[] 申请的数组,可能会导致未完全析构的对象泄漏。


Day5 类的定义和关键字再探(2025.03.24)

1. C++ 关键字 conststaticextern

const int global_a = 10;  // 只读常量
static int s_b = 10;      // 静态全局变量(仅限当前文件可见)
extern int SIZE = 10;     // 外部变量(多个文件可共享)
  • const:用于定义只读变量,防止意外修改。
  • static:修饰局部变量时,延长变量生命周期,修饰全局变量时,限制其作用域。
  • extern:用于声明外部变量,使其可以在多个文件中访问。

示例:

void test() {static int fun_c = 0;  // 仅初始化一次,生命周期贯穿整个程序fun_c++;cout << "fun_c = " << fun_c << endl;
}

2. 类的定义:Circle 和 Rect

class Circle {
public:Circle(double r = 0) : _r(r) {cout << "Circle()" << endl;}~Circle() {cout << "~Circle()" << endl;}double getArea() const {return M_PI * _r * _r;}private:double _r;
};

要点:

  • 构造函数(Constructor): 负责初始化对象,可以带默认参数。
  • 析构函数(Destructor): 负责清理资源,名称前带 ~
  • 成员函数(Member Function): const 关键字保证不会修改对象数据。

3. 完整代码

#define _USE_MATH_DEFINES
#include <iostream>
#include <cmath>using namespace std;
//关键字
//const
const int global_a = 10;
//static
static int s_b = 10;
//extern
extern int SIZE  = 10;
//三者的用途:const 修饰常量,static 修饰全局变量,extern 修饰外部变量void test()
{int local_v = 0;static int fun_c;//静态局部变量 可以延长变量的生命周期fun_c++;cout << "local_v = " << " " << local_v << " ," << "fun_c = " << " " << fun_c << endl;
}//定义一个圆
class Circle
{
public:Circle(double r = 0): _r(r){cout << "Circle(double r = 0)" << endl;}Circle(double r,char* name): _r(0), _name(new char[strlen(name) + 1]){strcpy_s(_name, strlen(name) + 1,name);cout << "Circle(double r = 0)" << endl;}~Circle(){cout << "~Circle()" << endl;}double getRadius() const{return _r;}//setRadiusvoid setRadius(double r){_r = r;}double getArea() const{return M_PI * _r * _r;}private:double _r;char* _name;
};//定义一个矩形
class Rect
{
public:Rect(double l = 0, double w = 0): _l(l), _w(w){cout << "Rect(double l = 0, double w = 0)" << endl;}~Rect(){cout << "~Rect()" << endl;}private:double _l;double _w;
};void testCircle()
{Circle c1(10);cout << "c1.getRadius() = " << c1.getRadius() << endl;cout << "c1.getArea() = " << c1.getArea() << endl;cout << endl << endl;Circle c2;c2.setRadius(20);cout << "c2.getRadius() = " << c2.getRadius() << endl;cout << "c2.getArea() = " << c2.getArea() << endl;
}int main()
{test();test();test();cout << endl << endl;testCircle();return 0;
}

Day5-1 运算符重载(2025.03.24)

1. 复数类 Complex 及其运算符重载

class Complex {friend Complex operator*(const Complex& lhs, const Complex& rhs);
public:Complex(double r = 0, double i = 0) : _real(r), _imag(i) {}Complex operator-(const Complex& rhs) const {return Complex(_real - rhs._real, _imag - rhs._imag);}Complex& operator++() {  // 前置++++_real;++_imag;return *this;}Complex operator++(int) {  // 后置++Complex tmp(*this);_real++;_imag++;return tmp;}Complex& operator+=(const Complex& rhs) {_real += rhs._real;_imag += rhs._imag;return *this;}void display() const {cout << _real << " + " << _imag << "i" << endl;}private:double _real;double _imag;
};

2. 运算符重载的几种方式

  • 成员函数重载(适用于 +=++-):

    Complex operator-(const Complex& rhs) const;
    Complex& operator++();
    Complex operator++(int);
    Complex& operator+=(const Complex& rhs);
    
  • 友元函数重载(适用于 +*):

    friend Complex operator+(const Complex& lhs, const Complex& rhs);
    friend Complex operator*(const Complex& lhs, const Complex& rhs);
    

3. 关键区别

运算符适用方式说明
+普通函数需要访问两个对象的数据,可用友元函数
-成员函数只需要访问当前对象数据
++成员函数影响当前对象,前置++返回引用,后置++返回值
*友元函数需要访问两个对象的数据

示例代码:

Complex c1(1, 2), c2(3, 4);
Complex c3 = c1 + c2;
c3.display();

总结:

  • 友元函数适用于二元运算(如 +*)。
  • 成员函数适用于一元运算(如 ++)和复合赋值运算(如 +=)。

4.完整代码

#include <iostream>
#include <limits.h>using namespace std;//复数
class Complex
{friend Complex operator*(const Complex& lhs, const Complex& rhs);//Complex operator/(const Complex& rhs) const;
public:Complex(double r = 0, double i = 0): _real(r), _imag(i) {cout << "Complex(double r = 0, double i = 0)" << endl;}~Complex(){cout << "~Complex()" << endl;}double getReal() const{return _real;}double getImag() const{return _imag;}//运算符重载之成员函数Complex operator-(const Complex& rhs) const{return Complex(_real - rhs._real, _imag - rhs._imag);}//自增运算符重载Complex& operator++() //前置++{++_real;++_imag;return *this;}//后置自增运算符重载Complex operator++(int) //后置++{Complex tmp(*this);_real++;_imag++;return tmp;//返回类型是一个临时对象,所以不适用引用类型}//前置++和后置++的区别?//解答:前置++返回是对象的引用,是左值可以取地址//后置++返回的是局部对象,是右值不能取地址//+=运算符重载//复合赋值运算符重载,推荐以成员函数的形式重载Complex& operator+=(const Complex& rhs){_real += rhs._real;_imag += rhs._imag;return *this;}void display() const{if (_imag > 0){cout << _real << " + " << _imag << "i" << endl;}else if (_imag == 0){cout << _real << endl;}else{cout << _real << " - " << -_imag << "i" << endl;}}
private:double _real;double _imag;
};	//“operator + ”必须至少有一个类类型的形参
//int operator+(int lhs, int rhs)
//{
//	//return _real + rhs;
//}//运算符重载之普通函数
Complex operator+(const Complex& lhs, const Complex& rhs)
{return Complex(lhs.getReal() + rhs.getReal(), lhs.getImag() + rhs.getImag());
}//运算符重载之友元函数(推荐使用)
Complex operator*(const Complex& lhs, const Complex& rhs)
{return Complex(lhs._real * rhs._real - lhs._imag * rhs._real,lhs._real * rhs._real + lhs._real * rhs._real);
}void test()
{Complex c1(1, 2);cout << "c1 = ";c1.display();cout << endl << endl;Complex c2(3, 4);cout << "c2 = ";	c2.display();cout << endl << endl;Complex c3 = c1 + c2;cout << "c3 = c1 + c2 = ";c3.display();
}void test2()
{Complex c1(1, 2);cout << "c1 = ";c1.display();cout << endl << endl;Complex c2(3, 4);cout << "c2 = ";	c2.display();cout << endl << endl;Complex c3 = c1 - c2;cout << "c3 = c1 - c2 = ";c3.display();}void test3()
{Complex c1(1, 2);cout << "c1 = ";c1.display();cout << endl << endl;Complex c2(3, 4);cout << "c2 = ";c2.display();cout << endl << endl;Complex c3 = c1 * c2;cout << "c3 = c1 * c2 = ";c3.display();c3 += c1;cout << "c3 += c1 = ";c3.display();}void test4()
{Complex c3(4, 6);cout << "c3 = ";c3.display();cout << endl << endl;++c3;cout << "++c3 = ";c3.display();cout << endl << endl;c3++;cout << "c3++ = ";c3.display();Complex c4(4, 6);cout << "c4 = ";c4.display();c4++;cout << "c4++ = ";c4.display();cout << "前置++返回是对象的引用,是左值可以取地址,后置++返回的是局部对象,是右值不能取地址";
}int main(int argc, char*  argv[])
{//test();//test2();//test3();test4();return 0;
}

http://www.mrgr.cn/news/95797.html

相关文章:

  • 数据结构之优先级队列
  • Atlas 800I A2 双机直连部署DeepSeek-R1-w8a8
  • Go常见问题与回答(下)
  • poetry安装与使用
  • 华为交换相关
  • vmwaretools解压失败|vmware tools distrib cannot mkdir read only file system|bug汇总
  • Linux 练习一 NFS和DNS
  • Floyd 算法--多源最短路
  • 利用dify打造命令行助手
  • Spring Boot整合Activiti工作流详解
  • 【Redis实战专题】「技术提升系列」​RedisJSON核心机制与实战应用解析(入门基础篇)
  • 调语音类大模型必备-音频录制小妙招-自制工具-借助浏览器录一段单声道16000采样率wav格式音频
  • 华为OD机试 - 核酸最快检测效率 - 动态规划、背包问题(Java 2024 E卷 200分)
  • 【学习记录】大模型微调之使用 LLaMA-Factory 微调 Qwen系列大模型,可以用自己的数据训练
  • How to share files with Linux mint 22 via samba in Windows
  • Sql Server 索引性能优化 分析以及分表
  • _DISPATCHER_HEADER结构中的WaitListHead和_KWAIT_BLOCK的关系
  • Linux的SPI子系统的原理和结构详解【SPI控制器(spi_master)、SPI总线(device-driver-match匹配机制)、SPI设备、SPI万能驱动`spidev.c`】
  • Unity 实现一个简易可拓展性的对话系统
  • 深度解读DeepSeek:开源周(Open Source Week)技术解读