C++进阶(二)

目录

1、Vector2D  默认构造、重载

2、char 深度理解

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


1、Vector2D  默认构造、重载

#include 
#include 

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 

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++,开发语言)