C++进阶(二)

2023-09-20 17:40:01

目录

1、Vector2D  默认构造、重载

2、char 深度理解

3、深度理解简单的类操作


1、Vector2D  默认构造、重载

#include <iostream>
#include <cmath>

class Vector2D {
private:
    double x; // X坐标
    double y; // Y坐标

public:
    // 默认构造函数,将向量初始化为(0,0)
    Vector2D() : x(0), y(0) {}

    // 带有两个参数的构造函数,用于初始化向量的x和y坐标
    Vector2D(double x, double y) : x(x), y(y) {}

    // 计算向量的长度
    double length() const {
        return std::sqrt(x * x + y * y);
    }

    // 重载+运算符,用于向量的加法
    Vector2D operator+(const Vector2D& other) const {
        return Vector2D(x + other.x, y + other.y);
    }

    // 打印向量的坐标
    void print() const {
        std::cout << "(" << x << ", " << y << ")" << std::endl;
    }
};

int main() {
    Vector2D v1(3, 4);
    Vector2D v2(1, 2);
    
    Vector2D v3 = v1 + v2;
    
    v3.print(); // 输出:(4, 6)
    
    return 0;
}

2、char 深度理解

背景

char* outex()
{
	char szP[32] = "helllo";

	return szP;
} 我理解是 szP的栈空间应该是被释放了 那么 return的时候 是把内容复制到返回值了?然后再释放的?
您的理解是正确的,`szP` 在 `outex` 函数中是一个栈上的局部变量。当函数返回时,这块栈空间会被标记为可以重用,但是不会立即被清零或释放。然而,返回一个栈上局部变量的指针是危险的,因为这块内存随时都可能被其他函数调用或其他局部变量覆盖,导致不确定的行为。

当您执行以下代码:

```cpp
char* ptr = outex();
```

您得到的 `ptr` 实际上是指向一个已经不再保证其内容的内存区域。这块内存很快就可能被其他操作覆盖。

要修复这个问题,有以下几种常见方法:

1. **静态存储**:使变量静态,这样它的生命周期会持续到程序结束。
    ```cpp
    char* outex() {
        static char szP[32] = "hello";
        return szP;
    }
    ```
    注意:这种方法使得每次调用 `outex` 都返回相同的内存地址,所以如果您修改这块内存的内容,将影响所有引用该地址的地方。

2. **动态内存分配**:使用 `new` (或 `malloc` 在 C 中)为字符串分配堆内存。
    ```cpp
    char* outex() {
        char* szP = new char[32];
        strcpy(szP, "hello");
        return szP;
    }
    ```
    如果使用这种方法,您必须确保在使用完返回的指针后使用 `delete[]` (或 `free` 在 C 中)来释放分配的内存,以避免内存泄漏。

3. **使用 C++ 标准库的字符串**:这是一个更现代和安全的方法。
    ```cpp
    std::string outex() {
        return "hello";
    }
    ```

在大多数情况下,推荐使用第三种方法,因为它最简单、安全。

3、深度理解简单的类操作

#include <iostream>

class SimpleClass {
private:
    int value;

public:
    SimpleClass(int v) : value(v) {}

    int getValue() const {
        return value;
    }

    void setValue(int v) {
        value = v;
    }
};

int main() {
    SimpleClass obj(5);
    std::cout << "Initial value: " << obj.getValue() << std::endl;

    obj.setValue(10);
    std::cout << "Updated value: " << obj.getValue() << std::endl;

    return 0;
}


这个程序首先定义了一个名为`SimpleClass`的类,然后在`main`函数中实例化并使用该类。下面是其深层次的工作原理:

1. **内存模型**:  
   当`SimpleClass obj(5);`这行代码执行时,编译器在栈上为`SimpleClass`对象分配内存。这意味着`obj`对象的生命周期限制在其声明的作用域内,一旦离开这个作用域(例如`main`函数结束时),对象就会被销毁。

2. **构造函数**:  
   `SimpleClass(int v) : value(v) {}`是一个带有一个整数参数的构造函数。在构造函数的初始化列表中,我们直接将成员变量`value`初始化为参数`v`的值。

3. **成员函数**:  
   `getValue`和`setValue`是访问器函数,它们允许我们访问和修改私有成员`value`。

4. **数据封装**:  
   通过将`value`设为`private`,我们确保了它不能直接从类外部访问或修改。这是面向对象编程的基本原则之一,称为封装。

5. **输入/输出流**:  
   `std::cout`是C++的一个输出流对象,它用于将文本发送到标准输出(通常是屏幕)。`<<`操作符被重载,以便可以与`std::cout`和其他类型的数据一起使用,从而提供连续的输出操作。

6. **返回值**:  
   `main`函数的返回值通常指示程序的退出状态。返回0通常表示程序成功完成。

编译和运行该程序会输出:
```
Initial value: 5
Updated value: 10
```

当你编译这段代码时,编译器会执行许多任务,包括但不限于:词法分析、语法分析、语义分析、优化和代码生成。然后链接器接手,解析库依赖关系,并生成可执行文件。

更多推荐

c++Flood Fill算法之池塘计数,城堡问题,山峰与山谷(acwing)

FloodFill算法有很多应用场景,以下是一些常见的应用场景:1.图像处理:在图像处理中,我们通常需要对图像的某一个区域进行涂色、填充、描边等操作,FloodFill算法就可以用来实现这些操作。2.游戏开发:在游戏中,FloodFill算法可以用来实现区域填充、地图探索、迷宫求解等功能。3.自动化绘制:FloodFi

如何用ate自动测试设备对DC-DC电源模块负载调整率进行测试?

电源模块负载调整率测试是功能测试之一,是电源模块非常重要的一项指标,它的大小直接影响着电源模块的整体质量。因此使用ate自动测试设备对DC-DC电源模块负载调整率进行测试是制造生产过程中至关重要的一环。电源模块负载调整率计算公式:负载调整率=(满载输出电压-空载输出电压)/额定输出电压*100%测量电源模块的负载调整率

解决高并发问题

在处理项目中的高并发问题时,可以采取以下几种方法:后端处理:大部分的高并发处理是在后端进行的。可以通过优化数据库查询、增加缓存机制(如集成Redis)、使用分布式技术(如分布式缓存、分布式锁)、使用消息队列等方式来提高系统的并发处理能力。此外,还可以通过水平扩展(增加服务器数量)或垂直扩展(增加服务器的硬件配置)来提高

Kafka【命令行操作】

Kafka命令行操作Kafka主要包括三大部分:生产者、主题分区节点、消费者。1、Topic命令行操作也就是我们kafka下的脚本kafka-topics.sh的相关操作。常用命令行操作参数描述--bootstrap-server<String:servertoconnectto>连接的KafkaBroker主机名称和

【Android Framework系列】第15章 Fragment+ViewPager与Viewpager2相关原理

1前言上一章节【AndroidFramework系列】第14章Fragment核心原理(AndroidX版本)我们学习了Fragment的核心原理,本章节学习常用的Fragment+ViewPager以及Fragment+ViewPager2的相关使用和一些基本的源码分析。2Fragment+ViewPager我们常用

腾讯mini项目-【指标监控服务重构】2023-07-19

今日已办OpenTelemetryLogs通过日志记录API支持日志收集集成现有的日志记录库和日志收集工具Overview日志记录API-LoggingAPI,允许您检测应用程序并生成结构化日志旨在与其他telemertydata(例如metric和trace)配合使用,以提供统一的可观测性解决方案结构化日志记录,允许

预处理代码

一、缺失值处理删除缺失值:data1=data.dropna()#丢弃缺失值#dropna()删除缺失值所在行(axis=0)或列(axis=1),默认为axis=0补全示例数据:importpandasaspdimportnumpyasnpdata=pd.DataFrame({'name':['Bob','Mary'

一篇搞定,Kettle详细教程

文章目录第一章Kettle概述1.1Kettle发展历程1.2Kettle简介1.3Kettle相关俗语1.4Kettle设计与组成1.5Kettle功能模块1.6Kettle的执行Transformation(转换)1.7Kettle商业和社区版区别1.8数据集成与ETL1.9ETL工具比较第二章Kettle安装部署

【python基础】编写/运行hello world项目

1.编写helloworld项目编程界每种语言的第一个程序往往都是输出helloworld。因此我们来看看,如何用Python输出helloworld。1.如果你是初学者,main.py中的代码暂时是无法看懂的,所以可以把main中的源代码直接删除。如下所示这里我们要学习python的第一个知识点,print输出函数。

机器学习(14)---逻辑回归(含手写公式、推导过程和手写例题)

逻辑回归一、逻辑回归概述二、模型、策略和优化(手写)三、w和b的梯度下降公式推导四、例题分析4.1题目4.2解答一、逻辑回归概述1.逻辑回归也称作logistic回归分析,是一种广义的线性回归分析模型,属于机器学习中的监督学习。其推导过程与计算方式类似于回归的过程,但实际上主要是用来解决二分类问题(当然也可以解决多分类

项目实战— pytorch搭建CNN处理MNIST数据集

项目文件夹介绍项目文件夹CNN_MNIST_practice文件夹是整个项目的文件夹,里面存放了六个子文件夹以及四个.py程序,接下来我们分别来介绍这些文件的内容。其中minist_all_CPU.py是CPU版本的模型训练+测试程序,而minist_all_GPU.py则是GPU版本的模型训练+测试程序。minist

热文推荐