学习构造函数与析构函数wid

学习C++ -> 构造函数与析构函数

一、构造函数的介绍    1. 构造函数的作用        构造函数主要用来在创建对象时完成对对象属性的一些初始化等操作, 当创建对象时, 对象会自动调用它的构造函数。一般来说, 构造函数有以下三个方面的作用:            ■ 给创建的对象建立一个标识符;            ■ 为对象数据成员开辟内存空间;            ■ 完成对象数据成员的初始化。            2. 默认构造函数        当用户没有显式的去定义构造函数时, 编译器会为类生成一个默认的构造函数, 称为 "默认构造函数", 默认构造函数不能完成对象数据成员的初始化, 只能给对象创建一标识符, 并为对象中的数据成员开辟一定的内存空间。            3. 构造函数的特点        无论是用户自定义的构造函数还是默认构造函数都主要有以下特点:            ①. 在对象被创建时自动执行;            ②. 构造函数的函数名与类名相同;            ③. 没有返回值类型、也没有返回值;            ④. 构造函数不能被显式调用。

二、构造函数的显式定义    由于在大多数情况下我们希望在对象创建时就完成一些对成员属性的初始化等工作, 而默认构造函数无法满足我们的要求, 所以我们需要显式定义一个构造函数来覆盖掉默认构造函数以便来完成必要的初始化工作, 当用户自定义构造函数后编译器就不会再为对象生成默认构造函数。        在构造函数的特点中我们看到, 构造函数的名称必须与类名相同, 并且没有返回值类型和返回值, 看一个构造函数的定义:

编译运行的结果:

代码说明:        在Point类的 public 成员中我们定义了一个构造函数 Point() , 可以看到这个Point构造函数并不像 printPoint 函数有个void类型的返回值, 这正是构造函数的一特点。在构造函数中, 我们输出了一句提示信息, "自定义的构造函数被调用...", 并且将对象中的数据成员xPos和yPos初始化为100。                在 main 函数中, 使用 Point 类创建了一个对象 M, 并调用M对象的方法 printPoint 输出M的属性信息, 根据输出结果看到, 自定义的构造函数被调用了, 所以 xPos和yPos 的值此时都是100, 而不是一个随机值。                需要提示一下的是, 构造函数的定义也可放在类外进行。

三、有参数的构造函数    在上个示例中实在构造函数的函数体内直接对数据成员进行赋值以达到初始化的目的, 但是有时候在创建时每个对象的属性有可能是不同的, 这种直接赋值的方式显然不合适。不过构造函数是支持向函数中传入参数的, 所以可以使用带参数的构造函数来解决该问题。

编译运行的结果:

代码说明:        在这个示例中的构造函数 Point(int x = 0, int y = 0) 使用了参数列表并且对参数进行了默认参数设置为0。在 main 函数中共创建了三个对象 M, N, P。            M对象不使用默认参数将M的坐标属性初始化10和20;            N对象使用一个默认参数y, xPos属性初始化为200;            P对象完全使用默认参数将xPos和yPos初始化为0。

三、构造函数的重载    构造函数也毕竟是函数, 与普通函数相同, 构造函数也支持重载, 需要注意的是, 在进行构造函数的重载时要注意重载和参数默认的关系要处理好, 避免产生代码的二义性导致编译出错, 例如以下具有二义性的重载:

在上面的重载中, 当尝试用 Point 类重载一个无参数传入的对象 M 时, Point M; 这时编译器就报一条 error: call of overloaded 'Point()' is ambiguous 的错误信息来告诉我们说 Point 函数具有二义性, 这是因为 Point(int x = 0, int y = 0) 全部使用了默认参数, 即使我们不传入参数也不会出现错误, 但是在重载时又重载了一个不需要传入参数了构造函数 Point(), 这样就造成了当创建对象都不传入参数时编译器就不知道到底该使用哪个构造函数了, 就造成了二义性。

四、初始化表达式    对象中的一些数据成员除了在构造函数体中进行初始化外还可以通过调用初始化表来进行完成, 要使用初始化表来对数据成员进行初始化时使用 : 号进行调出, 示例如下:

在 Point 构造函数头的后面, 通过单个冒号 : 引出的就是初始化表, 初始化的内容为 Point 类中int型的 xPos 成员和 yPos成员, 其效果和 xPos = x; yPos = y; 是相同的。        与在构造函数体内进行初始化不同的是, 使用初始化表进行初始化是在构造函数被调用以前就完成的。每个成员在初始化表中只能出现一次, 并且初始化的顺序不是取决于数据成员在初始化表中出现的顺序, 而是取决于在类中声明的顺序。        此外, 一些通过构造函数无法进行初始化的数据类型可以使用初始化表进行初始化, 如: 常量成员和引用成员, 这部分内容将在后面进行详细说明。使用初始化表对对象成员进行初始化的完整示例:

五、析构函数    与构造函数相反, 析构函数是在对象被撤销时被自动调用, 用于对成员撤销时的一些清理工作, 例如在前面提到的手动释放使用 new 或 malloc 进行申请的内存空间。析构函数具有以下特点:        ■ 析构函数函数名与类名相同, 紧贴在名称前面用波浪号 ~ 与构造函数进行区分, 例如: ~Point();        ■ 构造函数没有返回类型, 也不能指定参数, 因此析构函数只能有一个, 不能被重载;        ■ 当对象被撤销时析构函数被自动调用, 与构造函数不同的是, 析构函数可以被显式的调用, 以释放对象中动态申请的内存。

当用户没有显式定义析构函数时, 编译器同样会为对象生成一个默认的析构函数, 但默认生成的析构函数只能释放类的普通数据成员所占用的空间, 无法释放通过 new 或 malloc 进行申请的空间, 因此有时我们需要自己显式的定义析构函数对这些申请的空间进行释放, 避免造成内存泄露。

编译运行的结果:

代码说明:        代码中创建了一个 Book 类, 类的数据成员只有一个字符指针型的 bookName, 在创建对象时系统会为该指针变量分配它所需内存, 但是此时该指针并没有被初始化所以不会再为其分配其他多余的内存单元。在构造函数中, 我们使用 new 申请了一块 strlen(name)+1 大小的空间, 也就是比传入进来的字符串长度多1的空间, 目的是让字符指针 bookName 指向它, 这样才能正常保存传入的字符串。                在 main 函数中使用 Book 类创建了一个对象 CPP, 初始化 bookName 属性为 "C++ Primer"。从运行结果可以看到, 析构函数被调用了, 这时使用 new 所申请的空间就会被正常释放。                自然状态下对象何时将被销毁取决于对象的生存周期, 例如全局对象是在程序运行结束时被销毁, 自动对象是在离开其作用域时被销毁。             如果需要显式调用析构函数来释放对象中动态申请的空间只需要使用 对象名.析构函数名(); 即可, 例如上例中要显式调用析构函数来释放 bookName 所指向的空间只要:

THE END
0.C++构造函数详解:初始化对象的艺术本文详细介绍了C++中的构造函数,包括其概念、类型(无参、带参及全缺省)、默认构造函数的意义以及C++11中对缺省值的处理。通过实例说明了构造函数如何简化对象初始化过程。 💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤 jvzquC41dnuh0lxfp0tfv8qwjcuscw=361gsvrhng1jfvjnnu1746=5943?
1.C++:类的默认成员函数如果一个类中什么成员都没有,简称为空类。空类中什么都没有吗?并不是的,任何一个类在我们不写的情况下,都会自动生成6个默认成员函数。 【默认成员函数概念】:用户没有显式实现,编译器会生成的成员函数称为默认成员函数 其中两个默认成员函数是用来初始化和清理的分别为:构造函数、析构函数 jvzquC41dnuh0lxfp0tfv8|gkzooa=:253>138ftvkimg8igvcomu8655;<25;5
2.构造函数:c++C++ language reference Welcome back to C++ (Modern C++) Lexical conventions Basic concepts Built-in types Declarations and definitions Built-in operators, precedence, and associativity Expressions Statements Namespaces Enumerations Unions Functions jvzquC41oujo0vnetqyph}3eqo5{j6hp1noctjw{1u77z€6c:0gtr
3.C++构造函数和析构函数(Constructors&Destructors)详解C语言由于global object的诞生比程序进入更早点,所以global object的constructor执行的时间更早于程序的进入点,所谓的default constructor就是没有指定任何的参数的constructor,这篇文章主要介绍了C++ 构造函数和析构函数的相关知识,需要的朋友可以参考下+ 目录 GPT4.0+Midjourney绘画+国内大模型 会员永久免费使用!【 如果你想jvzquC41yy}/lk:30pku1ywqitgn1<7278;k:}3jvo
4.构造函数详解类的6个默认的成员函数 构造函数的概念: 构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,保证每个数据成员都有一个合适的初始值,并且在对象的生命周期内只调用一次。 构造函数的特性 函数名与类名相同。 无返回值。 jvzquC41yy}/extpqvk/exr1errvuyqwu/tpvn4eqpyut~hvqt4ivvq
5.Java构造函数具有公共访问级别的构造函数可以在程序的任何部分中使用。 具有私有访问级别的构造函数只能在声明它的同一类中使用。 具有受保护访问级别的构造函数可以在具有在其中声明类的相同包的程序中以及在任何包中的任何后代类内使用。 具有包级访问权限的构造函数可以在声明其类的同一个包中使用。 jvzquC41yy}/y
6.C++拷贝构造函数(复制构造函数)详解当以拷贝的方式初始化一个对象时,会调用一个特殊的构造函数,就是拷贝构造函数(Copy Constructor)。 下面的例子演示了拷贝构造函数的定义和使用: #include<iostream> #include<string> usingnamespacestd; classStudent{ public: Student(stringname="",intage=0,floatscore=0.0f);//普通构造函数 jvzquC41e0hjcwhjgpm/pny1xkkx1;8560nuou
7.PHP:构造函数和析构函数Please be aware of when using __destruct() in which you are unsetting variables Consider the following code: ; } function__destruct() { if($this->error_reporting===true)$this->show_report(); unset($this->error_reporting); jvzquC41yy}/rqu0pgz0njsiwcmf0xtr70jfexs
8.构造函数(C++)|MicrosoftLearn如果类未定义移动构造函数,则在没有用户声明的复制构造函数、复制赋值运算符、移动赋值运算符或析构函数时,编译器会生成隐式构造函数。 如果未定义显式或隐式移动构造函数,则原本使用移动构造函数的操作会改用复制构造函数。 如果类声明了移动构造函数或移动赋值运算符,则隐式声明的复制构造函数会定义为已删除。jvzquC41fqit0vnetqyph}3eqo5{j6hp1evq1lur1euou}wwevusu6hrr
9.C++构造函数详解:一篇搞懂所有构造函数知识(含代码+图解)当你没有定义任何构造函数时,编译器会自动生成一个“空的默认构造函数”。 classStudent{ public: intage; }; intmain(){ Student s;// 默认构造函数被调用(编译器生成) s.age =20; } AI写代码cpp 运行 但如果你一旦写了带参数的构造函数,编译器就不会再生成默认构造函数了,你需要手动写一个! jvzquC41dnuh0lxfp0tfv8|gkzooa?:2:2>9:8ftvkimg8igvcomu866;66:9<=
10.C++——构造函数构造函数是C++中一种特殊的成员函数,它在创建类对象时自动调用,用于初始化对象。 构造,那构造的是什么呢? 构造成员变量的初始化值,内存空间等 一、构造函数的基本概念 定义:构造函数是与类同名的特殊成员函数 特点: 没有返回类型(连void都没有) 创建对象时自动调用 通常声明为public(除非有特殊需求) 可以重载(一个类可以有多个构 jvzquC41dnuh0lxfp0tfv8|gkzooa?6448:548ftvkimg8igvcomu86692617A8
11.JAVA中的构造函数(方法)java这篇文章主要介绍了JAVA中的构造函数(方法),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教+ 目录 一、什么是构造函数 Java构造函数,也叫构造方法,是JAVA中一种特殊的函数。与函数名相同,无返回值。 作用:一般用来初始化成员属性和成员方法的,即new对象产生后,就调用了对象的属性和方法。jvzquC41yy}/lk:30pku1ywqitgn1<6:687cov3jvo
12.C++超详细讲解构造函数C语言可以看到使用编译器生成的默认构造函数我们的日期仍然是随机值。 无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。注意:无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为是默认构造函数。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 jvzquC41yy}/lk:30pku1jwvkerf1;:2448/j}r
13.构造函数前面的示例显示了初始化新对象的实例构造函数。 类或结构还可以声明静态构造函数,该构造函数初始化类型的静态成员。 静态构造函数是无参数的。 如果未提供静态构造函数来初始化静态字段,C# 编译器会将静态字段初始化为默认值,如C# 类型的默认值文章中所列。 jvzquC41oujo0vnetqyph}3eqo5{j6hp1noctjw{1cif7qg|j0gtr
14.构造函数(C++)|MicrosoftLearn如果类未定义移动构造函数,则在没有用户声明的复制构造函数、复制赋值运算符、移动赋值运算符或析构函数时,编译器会生成隐式构造函数。 如果未定义显式或隐式移动构造函数,则原本使用移动构造函数的操作会改用复制构造函数。 如果类声明了移动构造函数或移动赋值运算符,则隐式声明的复制构造函数会定义为已删除。jvzquC41fqit0vnetqyph}3eqo5{j6HP1evq1lur1euou}wwevusu6hrrA|jg€Bouxi.3=5
15.构造函数前面的示例显示了初始化新对象的实例构造函数。 类或结构还可以声明静态构造函数,该构造函数初始化类型的静态成员。 静态构造函数是无参数的。 如果未提供静态构造函数来初始化静态字段,C# 编译器会将静态字段初始化为默认值,如C# 类型的默认值文章中所列。 jvzquC41oujo0vnetqyph}3eqo5{j6hp1noctjw{1cif7qg|j
16.构造函数基实例构造函数运行。以 Object.Object 开头从每个基类到直接基类的任何实例构造函数。 实例构造函数开始运行。 该类型的实例构造函数运行。 对象初始值设定项运行。 如果表达式包含任何对象初始值设定项,则它们在实例构造函数运行后运行。 对象初始值设定项按文本顺序运行。 使用new 运算符创建实例时,将执行上述操作。 jvzquC41fqit0vnetqyph}3eqo5{j6hp1fuupny1eunbty4rtqmscvrkpi3hwrig1erbu|ju/cte/|ytwezt1ltpuvxve}ttu
17.C++的6种构造函数c++构造函数以值方式返回局部对象(由于编译器的RVO【返回值优化】,所以不会返回对象时不会调用拷贝构造) 构造函数调用规则:默认情况下,编译器会给类至少添加三个函数:默认构造、拷贝构造、析构函数。如果自定义了有参构造,就不再提供无参构造,但会提供拷贝构造;如果自定义了拷贝构造,就不再提供其他构造函数。 jvzquC41dnuh0lxfp0tfv8|gkzooa=:3:8:378ftvkimg8igvcomu86626>86;5