C++类和对象的细节原理:this指针、构造函数和析构函数、深浅拷贝、运算符重载、初始化列表、类的各种成员和方法

简介: C++类和对象的细节原理:this指针、构造函数和析构函数、深浅拷贝、运算符重载、初始化列表、类的各种成员和方法

相关基础概念

OOP:面向对象编程。OOP语言的四大特征是抽象、封装/隐藏、继承、多态。

实体:比如人,一个人就是一个实体,比如表格,一张表格也可以是一个实体。

属性、行为:比如人的属性有年龄、身高、体重等,人的行为有吃喝拉撒等。

类:实体的抽象类型,比如一个人的类,就是先把人的属性、行为等抽象出来,虚虚地放在代码段上,仅仅是一个模板,类型是不占空间的。当要描述某个人的这个实体的时候,把这个类填充上属性即可,但是多个实体公用一套行为。实体的属性的抽象对应类的成员变量,实体的行为对应类的成员方法。属性一般是私有的,方法一般是公有的。

成员方法的实现方法:有类体内实现和类体外实现两种方法。类体内实现的方法自动转为inline函数。类体外实现需要在函数名称前面加上作用域和作用域解析符。

实例化:把类填充上属性,也叫类的实例化。

对象:类实例化的产物叫做对象。

This指针

类的成员方法一经编译,所有的方法参数,都会加一个this指针,接收调用该方法的对象的地址。

所以C++的good1.init(“面包”)实际上是C语言中的init(&good1,”面包”)。但是在C++中,当你调用一个成员函数时,编译器会自动传递调用该函数的对象的地址作为函数的隐含参数(即 this 指针),因此你无需手动传递对象的地址。通俗来说就是,C++的good1.init(“面包”),看起来没有传入&good1,但是在这个方法内部只要用了this这个关键字,就相当于在用&good1。

构造函数与析构函数

初始化和释放不一定要通过构造和析构函数完成,但是C++中为了保证代码的安全性,设置了构造和析构函数,析构函数能自行执行,构造函数必须自动或显式地执行以此保证我们不会忘记初始化。

构造函数:一般用于初始化对象成员变量。

析构函数:一般用于释放对象成员变量所占的外部堆内存。

构造函数的特点:1、不带返回值。2、与类同名。3、可以有多个形参列表不同的构造函数。4、构造函数会根据我们的传参自行选择是哪个函数。5、对象的创建必定经过构造函数。

析构函数的特点:1、不带返回值。2、~+类名。3、只能有一个。4、不能带参数。5、析构函数可以自行调用(不建议)。5、如果对象创建在堆上,需要自己手动删除,删除的时候回自动调用析构函数。6、一个程序可能会有多个对象需要析构,按反入栈的顺序进行析构。7、一个对象销毁前必定经过析构函数。

拷贝构造函数与深浅拷贝

形参类型是同类(比如const CClass &c)的构造函数就是拷贝构造函数。

CClass c2 = c1;

CClass c3(c1);

这两句代码都是在调用拷贝构造函数,是等价的。

默认情况下拷贝构造函数是把成员变量一一复制,如果有成员变量是地址,指向了堆内的空间,那么复制过来的成员变量指向了同一块堆内存空间,这是浅拷贝。

如果需要把堆内存空间也放到新开辟的堆空间里,我们需要在拷贝构造函数里自定义这个堆空间的开辟和复制过程,也就是深拷贝。

运算符重载

运算符重载(Operator Overloading)是 C++ 中的一种特性,允许你重新定义或扩展已有的运算符的行为,使其适用于自定义的类或数据类型。

比如赋值运算符重载,operator=有点类似一个被定义的函数。

class MyClass {
public:
    int value;
    MyClass& operator=(const MyClass& other) {
        if (this != &other) {
            value = other.value;
        }
        return *this;
    }
};

返回引用是支持连续的operator=赋值操作。

返回引用意味着是除了把*this作为返回值之外,operator=的左边如果是引用类型,那么operator=的左边的变量也是*this的引用。如果不是引用类型,那么返回值被当做右值使用。

构造函数的初始化列表

成员对象:B类变量是A类的成员变量之一,那么可以叫这个B类变量为A类的成员对象。

如果B类自定义了构造函数,那么默认构造函数会被覆盖掉,那么A类对象构造的时候无法自动调用B类对象的构造函数,就需要手动调用。

初始化列表的语法如下:

ClassName::ClassName(Type1 arg1, Type2 arg2, ...) : member1(arg1), member2(arg2), ... {

   // 构造函数的主体

}

初始化列表会省略类型。

假设menber1是int age,在初始化列表中member1(arg1)其实就是int age = arg1;

假设member2是CClass c,member2(arg2)其实就是CClass c(arg2);

注意:成员变量的初始化和他们定义顺序有关,和构造函数初始化列表中出现的先后顺序无关。

类的各种成员、方法

普通成员方法

  1. 属于类的作用域。
  2. 调用该方法的时候,需要依赖一个对象。
  3. 可以任意访问对象的私有成员变量。
  4. 默认传入了this指针。

Static成员变量

  1. 所有同类对象共享,所有对象都能操作它。
  2. 需要类外定义并且初始化。初始化方法:类型 作用域::变量名 = 值。
  3. 它不属于对象,属于类级别。本质是全局变量,但是作用域被限制在了类中。

Static成员方法

1、可以直接用类名::static方法的方式调用。如果每次访问static变量都需要通过某个对象,显然很别扭,因此诞生了static方法,可以不通过对象,而是通过类直接访问static变量。

2、因为调用它不依赖对象,所以它没有传入this指针,不方便访问普通的变量。

Const成员方法

如果创建对象的时候创建成了const类型的对象,那么普通的成员方法因为默认是非const的this指针,无法接受const类型的对象的指针。这时候就需要在普通方法的声明的右括号之后加const修饰,表示this指针形参被改成了const this指针形参。

建议如果是只涉及读操作的成员方法,都要加const修饰,这样const对象也能调用,常对象也能调用。

Const方法只能读私有成员,不能修改。

总结

普通成员方法、const成员方法、static成员方法,差别主要是玩的是不同this指针,const玩的是const this指针,static干脆不玩指针。

指向类的成员的指针

可以在类的作用域下定义指针,指向public的类的成员方法或成员变量。

调用这个指针的时候需要依赖具体的对象。

#include <iostream>
class MyClass {
public:
    void memberFunction(int x) {
        std::cout << "Member function called with argument: " << x << std::endl;
    }
    int memberVariable = 42;
};
int main() {
    // 声明指向成员函数的指针
    void (MyClass::*functionPtr)(int) = &MyClass::memberFunction;
    // 声明指向成员变量的指针
    int MyClass::*variablePtr = &MyClass::memberVariable;
    MyClass obj;
    // 通过对象调用成员函数
    (obj.*functionPtr)(10);
    // 通过对象调用成员变量
    std::cout << "Member variable value: " << obj.*variablePtr << std::endl;
    return 0;
}
目录
相关文章
|
1天前
|
存储 Java C++
【C++类和对象】探索static成员、友元以及内部类
【C++类和对象】探索static成员、友元以及内部类
|
1天前
|
安全 程序员 编译器
【C++类和对象】初始化列表与隐式类型转换
【C++类和对象】初始化列表与隐式类型转换
|
1天前
|
安全 编译器 C++
【C++类和对象】const成员函数及流插入提取
【C++类和对象】const成员函数及流插入提取
|
1天前
|
存储 C++
【C++类和对象】日期类的实现(下)
【C++类和对象】日期类的实现
|
1天前
|
编译器 C++
【C++类和对象】日期类的实现(上)
【C++类和对象】日期类的实现
|
1天前
|
编译器 C++ 索引
【C++类和对象】拷贝构造与赋值运算符重载(下)
【C++类和对象】拷贝构造与赋值运算符重载
|
1天前
|
存储 编译器 C++
【C++类和对象】拷贝构造与赋值运算符重载(上)
【C++类和对象】拷贝构造与赋值运算符重载
|
21天前
|
存储 C语言
C语言 — 指针进阶篇(下)
C语言 — 指针进阶篇(下)
20 0
|
21天前
|
存储 C语言 C++
C语言 — 指针进阶篇(上)
C语言 — 指针进阶篇(上)
27 0
|
27天前
|
存储 程序员 C语言
C语言指针的概念、语法和实现
在C语言中,指针是其最重要的概念之一。 本文将介绍C语言指针的概念、语法和实现,以及如何使用它们来编写高效的代码。
14 0