C++构造函数

1. 概述

本篇继续C++面向对象编程,包括像类啊,构造函数啊所有这些东西。那么什么是构造函数呢,构造函数基本上是一种特殊类型的方法,他在每次实例化对象时运行。所以我认为用一个例子来描述是最好的。假设我们想要创建一个Entity类

2. 案例

1. 准备项目

准备一个简单的项目,项目中有一个main.cpp文件,内容如下

2. 开始项目

我们想创建一个Entity类,它有两个成员变量float x, y,也就是描述entity的位置。

如果我试着创建一个Entity实例,然后给它一个print函数,这样它就能把它的内容输出到控制台。

我们实例化Entity后调用print函数。

F5运行我们的代码

可以看到它正常工作。然而我们的得到的Entity的位置看是随机的值,这是因为当我们实例化Entity,并为它分配内存时,我们实际上并没有初始化那个内存,这意味着我们得到了那个内存空间里原来的那些东西。

我们可能想做的是初始化内存,并将它设为0之类的,这样我们的位置默认为0。如果我们不指定或者设置一个值的话。

后面会继续深入类初始化的文章,这里保持简短。另一个很好的例子,如果我们决定手动打印x和y,因为他们是public的,那么我们可以继续尝试写代码打印出x

我们尝试编译代码,ctrl + F7

可以看到,我们得到了一个错误,使用了未初始化的局部变量"e"。也就是说,这个代码甚至都不会通过编译,因为我们试图使用没有初始化的内存。

这个Print()函数虽然可以通过编译,但是它显示的并不是我们所期望的,因为它打印的X和Y都设置了看似随机的值。

我们已经知道,需要某种初始化,我们需要一种方法,当构造一个Entity实例时,我们想要把X和Y设为0,除非已经被指定了其他值。我们可能想创建一个初始化的方法,因此我们来创建一个叫Init的方法。

现在,我们能做的是,当Entity对象实例创建时,我们可以调用e.Init()方法来初始化X,Y的值。

然后如果我试着打印我的值。F5运行程序

可以看到得到了0。当我们调用print()时,得到了0, 0。这意味着X和Y被设为0。

然而,我们额外编写了相当多的代码。我们需要定义Init方法,每当我们想在代码中创建一个Entity对象(实例),这意味着我们都需要实际运行Init函数。这就多了相当多的代码,相当的不清爽。

当我们构造对象时,如果我们有办法直接运行这个初始化代码就好了。于是,就有了构造函数

3. 构造函数

构造函数是一种特殊类型的方法,这是一种每次你构造一个对象时都会调用的方法。我们像定义其他方法一样定义它。然而,它没有返回类型,并且它的名称必须与类的名称相同。

写Entity类的构造函数时,首先是输入类名Entity,后接小括号,我们可以选择给出一个参数,我们一会讲到,或者完全空白。Entity(),然后我们可以给他一个函数主体,在这种情况下,我可以令X等于0,Y等于0

我们可以去掉Init的方法及其调用

如果现在运行代码 F5

会看到,我们得到的结果和Init方法得到的结果是一样的。然而,现在我们不需要Init方法了,Init方法被构造函数取代了。

4. 默认的构造函数

如果不指定构造函数,默认仍然会有一个构造函数,它只是一个叫做默认构造函数的东西。它默认情况下已经为我们准备好了。然而这个默认的构造函数实际上什么都没做。

它基本上和这个相等,函数体内完全空着。他什么也不做,没有为变量进行初始化。像java等语言,数据类型,比如int和float,会自动初始化为0。但C++不会,我们必须手动初始化所有基本类型。否则,它们将被设置为留在该内存中的其他什么值。所以非常非常重要的的是,不要忘记初始化。后续的文章会讲到更多关于初始化的内容,以及正确初始化内存的不同策略和方法。

现在,我们看一下带参数的构造函数,其实我们可以写很多的构造函数。当然,前提是它们有不同的参数。这个和我们写一些同名方法(函数)的时候是一样的。其实,这叫函数重载,即有相同的函数(方法)名,但是有不同的参数的不同函数版本。

也就是,我们将参数赋值给了我们的成员变量。

现在,我们可以选择使用参数来构造Entity对象了。

如果我们运行程序,当然10和50打印到控制台。

到这里,这个构造函数讲的差不多了。构造函数,当然,如果不实例化对象,将不会运行。所以如果我们只使用一个类的静态方法,构造函数是不会运行的。我们还没有讨论堆内存的分配问题。后续的文章中肯定会讲到。当然,当使用new关键字并创建一个对象实例时,它也会调用构造函数。

5. 删除构造函数

这里也有一些方法可以删除构造函数,例如,我们有一个log类,它只有静态的日志方法。

我不希望有人创建log类的实例,有两种不同的解决方法。

1. private,构造函数私有化

我们可以通过设置为private来隐藏构造函数。

可以看到我们在Log l;这里得到了一个错误,因为我们不能访问构造函数。

如果我们去掉private修饰构造

可以看到Log l;显然是允许构造对象的。C++为我们提供了一个默认构造函数。

2. delete删除构造函数

然而,我们可以告诉编译器,我们不需要这个默认构造函数,我们可以简单的写Log() = delete;

我们不能像这样Log l;这样调用log,因为默认构造函数已经被我们删除了,实际上并不存在。

还有一些特殊类型的构造函数,比如复制构造函数,还有移动构造函数,这每一个都是一篇单独的文章,因为它们都很复杂。但是对于基本的使用,这就是构造函数,一个特殊的方法,在我们创建类的实例时运行。它的主要用途是初始化该类,当我们创建一个新对象实例时,构造函数确保我们初始化了所有的内存,做了所有我们需要做的设置。

相关推荐
FL16238631298 分钟前
[C++]使用纯opencv部署yolov11-pose姿态估计onnx模型
c++·opencv·yolo
sukalot11 分钟前
windows C++-使用任务和 XML HTTP 请求进行连接(一)
c++·windows
ぃ扶摇ぅ29 分钟前
Windows系统编程(三)进程与线程二
c++·windows
Mr.Z.4111 小时前
【历年CSP-S复赛第一题】暴力解法与正解合集(2019-2022)
c++
Death2001 小时前
使用Qt进行TCP和UDP网络编程
网络·c++·qt·tcp/ip
郭二哈2 小时前
C++——list
开发语言·c++·list
黑不溜秋的2 小时前
C++ 语言特性29 - 协程介绍
开发语言·c++
一丝晨光2 小时前
C++、Ruby和JavaScript
java·开发语言·javascript·c++·python·c·ruby
￴ㅤ￴￴ㅤ9527超级帅3 小时前
LeetCode hot100---二叉树专题(C++语言)
c++·算法·leetcode
_GR3 小时前
每日OJ题_牛客_牛牛冲钻五_模拟_C++_Java
java·数据结构·c++·算法·动态规划