目录
- #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;
- }
背景
- 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";
- }
- ```
-
- 在大多数情况下,推荐使用第三种方法,因为它最简单、安全。
- #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
- ```
-
- 当你编译这段代码时,编译器会执行许多任务,包括但不限于:词法分析、语法分析、语义分析、优化和代码生成。然后链接器接手,解析库依赖关系,并生成可执行文件。