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

C++创建并初始化对象

文章目录

      • 一、对象的创建
        • 1.1 定义类
        • 1.2 创建对象
      • 二、对象的初始化
        • 2.1 默认构造函数
        • 2.2 带参数的构造函数
        • 2.3 初始化列表
      • 三、拷贝构造函数
      • 四、对象的销毁
      • 五、总结
    • 视频讲解笔记
      • 在栈上创建
      • 在堆上创建
        • new

在C++中,创建并初始化对象是面向对象编程(OOP)的核心操作之一。对象的创建与初始化主要通过类和构造函数来完成。以下是关于C++中对象的创建和初始化的详细教学。

一、对象的创建

1.1 定义类

在创建对象之前,首先需要定义一个类。类是对象的蓝图,定义了对象的属性和行为。类通常包含成员变量(属性)和成员函数(方法)。

示例:

class Person {
public:
    string name;
    int age;

    void display() {
        cout << "Name: " << name << ", Age: " << age << endl;
    }
};

在这个示例中,Person类包含两个成员变量nameage,以及一个成员函数display()用于显示对象的信息。

1.2 创建对象

创建对象的过程称为“实例化”。实例化是指通过类的定义创建一个类的对象。对象的创建可以在栈上或堆上进行。

栈上创建对象:

int main() {
    Person p1;  // 创建一个 Person 对象
    p1.name = "John";
    p1.age = 30;
    p1.display();  // 输出: Name: John, Age: 30
    return 0;
}

堆上创建对象:

int main() {
    Person* p2 = new Person;  // 在堆上创建一个 Person 对象
    p2->name = "Alice";
    p2->age = 25;
    p2->display();  // 输出: Name: Alice, Age: 25
    delete p2;  // 手动释放堆上的内存
    return 0;
}

在栈上创建的对象在作用域结束时自动销毁,而在堆上创建的对象则需要手动释放内存。

二、对象的初始化

对象的初始化可以通过构造函数来实现。构造函数是类的一种特殊成员函数,用于在对象创建时对其进行初始化。

2.1 默认构造函数

如果类中没有显式定义构造函数,编译器会自动生成一个默认构造函数。默认构造函数不接受参数,通常用于简单的对象初始化。

示例:

class Person {
public:
    string name;
    int age;

    Person() {
        name = "Unknown";
        age = 0;
    }

    void display() {
        cout << "Name: " << name << ", Age: " << age << endl;
    }
};

int main() {
    Person p1;  // 调用默认构造函数
    p1.display();  // 输出: Name: Unknown, Age: 0
    return 0;
}

在这个示例中,Person类定义了一个默认构造函数,该构造函数将name初始化为"Unknown",将age初始化为0

2.2 带参数的构造函数

带参数的构造函数允许在创建对象时传递参数,以便对对象进行更灵活的初始化。

示例:

class Person {
public:
    string name;
    int age;

    Person(string n, int a) {
        name = n;
        age = a;
    }

    void display() {
        cout << "Name: " << name << ", Age: " << age << endl;
    }
};

int main() {
    Person p1("John", 30);  // 调用带参数的构造函数
    p1.display();  // 输出: Name: John, Age: 30
    return 0;
}

在这个示例中,Person类的构造函数接受两个参数,并将它们用于初始化nameage

2.3 初始化列表

C++提供了初始化列表(Initializer List),用于在构造函数中直接初始化成员变量。初始化列表比在构造函数体内进行赋值更高效,尤其对于常量成员和引用成员来说是唯一的初始化方式。

示例:

class Person {
public:
    string name;
    int age;

    Person(string n, int a) : name(n), age(a) {}  // 使用初始化列表

    void display() {
        cout << "Name: " << name << ", Age: " << age << endl;
    }
};

int main() {
    Person p1("Alice", 25);
    p1.display();  // 输出: Name: Alice, Age: 25
    return 0;
}

在这个示例中,Person类的构造函数使用了初始化列表,这样做不仅简洁,而且避免了在构造函数体内进行额外的赋值操作。

三、拷贝构造函数

当一个对象被用作另一个对象的初始值或被传递给函数时,会调用拷贝构造函数。拷贝构造函数用于创建对象的副本。

示例:

class Person {
public:
    string name;
    int age;

    Person(string n, int a) : name(n), age(a) {}

    // 拷贝构造函数
    Person(const Person &p) {
        name = p.name;
        age = p.age;
    }

    void display() {
        cout << "Name: " << name << ", Age: " << age << endl;
    }
};

int main() {
    Person p1("John", 30);
    Person p2 = p1;  // 调用拷贝构造函数
    p2.display();  // 输出: Name: John, Age: 30
    return 0;
}

在这个示例中,Person类定义了一个拷贝构造函数。当创建对象p2时,调用拷贝构造函数将p1的值复制给p2

四、对象的销毁

对象的销毁是由析构函数完成的。析构函数用于释放对象在生存期内分配的资源。析构函数是一个没有返回值、没有参数、名称与类名相同并前置~符号的特殊成员函数。

示例:

class Person {
public:
    string name;
    int age;

    Person(string n, int a) : name(n), age(a) {}

    ~Person() {
        cout << name << " is being destroyed" << endl;
    }
};

int main() {
    Person p1("John", 30);
    return 0;  // 当 p1 超出作用域时,自动调用析构函数
}

在这个示例中,当p1超出作用域时,自动调用析构函数,输出信息表明对象正在被销毁。

五、总结

  • 对象的创建:可以在栈上或堆上创建对象,通过类的定义实例化对象。
  • 对象的初始化:主要通过构造函数完成,包括默认构造函数、带参数的构造函数和使用初始化列表。
  • 拷贝构造函数:用于创建对象的副本,在需要复制对象时调用。
  • 对象的销毁:由析构函数完成,用于释放资源。

掌握对象的创建和初始化是理解和使用C++面向对象编程的基础。通过合理地设计构造函数和析构函数,可以有效地管理对象的生命周期和资源的使用。

视频讲解笔记

创建并初始化C++ 对象,有两种方式:
1、如果你想手动控制它的创建和释放,以及需要的内存比较大,就在堆上创建,使用new,对应的需要delete,否则会出现内存泄漏;

2、栈上一般1–2M的内存,比较小,当时性能比堆上快,会在自己的作用域结束后自动释放。

在栈上创建

默认构造函数,已经初始化,不会有空指针异常。
在这里插入图片描述

在这里插入图片描述

在堆上创建

在这里插入图片描述

new

new,寻找一块连续的内存,然后把地址返回,所以创建时是:

Entity *e = new Entity();
寻找连续的地址也是根据空闲列表寻找,并不是逐行遍历那么笨拙;

在这里插入图片描述

在这里插入图片描述


http://www.kler.cn/a/286565.html

相关文章:

  • github制作静态网页
  • C++ 中用于控制输出格式的操纵符——setw 、setfill、setprecision、fixed
  • 团体程序设计天梯赛-练习集——L1-025 正整数A+B
  • vue-有关于TS与路由器
  • 关于opencv环境搭建问题:由于找不到opencv_worldXXX.dll,无法执行代码,重新安装程序可能会解决此问题
  • python学opencv|读取图像(四十九)使用cv2.bitwise()系列函数实现图像按位运算
  • vue项目安装pnpm和无法加载pnpm,已解决
  • jQuery库
  • 【Python机器学习】NLP词中的数学——主题建模
  • AI技术在巴黎奥运会中有哪些应用?
  • 用户管理和授权
  • XILINX平台下LINUX DMA驱动调研
  • 排序算法见解(2)
  • NDK编译c/c++文件成so库
  • CentOS 7 将YUM源更换为国内源的保姆级教程
  • OpenCV入门
  • OpenCPN Compiling on Windows
  • 【学习笔记】卫星通信NTN 3GPP标准化进展分析(三)- 3GPP Release17 内容
  • SYN6288语音合成模块的简单应用
  • [M二叉树] lc235. 二叉搜索树的最近公共祖先(dfs+二叉搜索树)
  • 如何使用mcu 内置 flash 实现fatfs
  • 原来这就是 布隆过滤器
  • 【JS】async函数返回promise
  • VR虚拟驾驶未来发展_vr自动驾驶汽车所带来的改变
  • 一次bad udp checksum故障
  • 深度解析CancellationToken在HttpClient请求中的应用