首页 > 编程语言 >C++中的类1

C++中的类1

时间:2023-08-13 11:02:08浏览次数:112  
标签:初始化 const 函数 对象 成员 C++ 构造函数

一、初始化列表

初始化列表是在 C++ 类的构造函数中使用的一种特殊语法。它允许在对象创建时对成员变量进行初始化。

C++中的类1_析构函数

通常,在构造函数的函数体中,我们会使用赋值操作符(=)来对成员变量进行初始化。然而,初始化列表提供了一种在构造函数签名之后的初始化成员变量的方式。


初始化列表使用冒号(:)后跟一个成员初始化列表。每个初始化列表由成员变量名和其对应的初始值构成,并用逗号分隔。


以下是初始化列表的基本语法:


ClassName(constructor_arguments) : member1(initial_value1), member2(initial_value2), ... {

    // 构造函数体

}


例如,考虑以下的示例类 Person,具有 name 和 age 成员变量:


class Person {

    std::string name;

    int age;


public:

    Person(const std::string& personName, int personAge) : name(personName), age(personAge) {

        // 构造函数体

    }

};


在上面的代码中,构造函数使用初始化列表来对 name 和 age 成员变量进行初始化。传递给构造函数的参数 personName 和 personAge 用于初始化列表,并通过冒号分隔。


使用初始化列表的好处有几个:


1.效率:初始化列表允许直接对成员变量进行初始化,而不是采用默认构造函数再赋值的方式。这样可以减少额外的构造和赋值操作,提高效率。


2.对于 const 成员和引用类型成员变量,它们只能通过初始化列表进行初始化。这是因为在构造函数体内无法对 const 成员和引用类型成员变量进行赋值操作。


3.初始化顺序:初始化列表可以用于指定成员变量的初始化顺序。成员变量的初始化顺序与在初始化列表中的顺序相同,而不是与它们在类定义中出现的顺序相同。


二、类中的const成员

在一个类(或结构体)中声明的 const 成员是指成员变量的值在对象创建后不能被修改。这意味着,一旦一个对象被创建并初始化,const 成员的值就不能再改变。


在类的定义中,可以使用 const 关键字来声明 const 成员。例如:


class MyClass {

    const int myConstMember;


public:

    MyClass(int value) : myConstMember(value) {

        // 构造函数中的初始化列表用于初始化const成员

    }

};


在上面的示例中,MyClass 类包含一个 const 成员 myConstMember,它被初始化为通过构造函数传递的值。


const 成员的主要特点是:


1.它们必须在构造函数的初始化列表中进行初始化。一旦初始化,就不能在类的其他成员函数中修改它们的值。


2.const 成员不能被修改,即不能被赋新值。任何修改 const 成员的尝试都会导致编译错误。


3.const 成员的值对于每个对象而言是唯一的,而不是共享的。每个对象都有自己的 const 成员副本。


MyClass obj1(10);

MyClass obj2(20);


obj1.myConstMember = 5;  // 错误,无法修改const成员的值

obj2.myConstMember++;    // 错误,无法修改const成员的值

const 成员通常用于表示对象的不可变属性,例如对象的常量配置,或者在类中提供只读的状态信息。


需要注意的是,const 成员的初始化只能在构造函数中进行,而不能在类体外部初始化,并且每个对象的 const 成员的值可以是不同的,取决于构造函数中传递的值。


三、析构函数

在C++中,析构函数(Destructor)是一种特殊的成员函数,它在对象被销毁时自动调用。析构函数的主要目的是进行资源的释放和清理操作。


析构函数的命名规则与类名相同,但在类名前加上波浪号(~)。它没有任何参数,也没有返回类型。一个类可以有一个析构函数,用于清理对象的资源,释放它所占用的内存或关闭打开的文件等。


以下是析构函数的基本语法:


class ClassName {

public:

    // 构造函数和其他成员函数


    ~ClassName() {

        // 析构函数的实现

    }

};


当对象的生命周期结束时,例如在以下情况下,析构函数会自动调用:


当对象被定义为自动变量,超出其作用域时。

当对象是动态分配的,通过 new 运算符创建,然后通过 delete 运算符释放它时。

当对象是类的成员,而其所属的类对象被销毁时,会自动调用成员对象的析构函数。


析构函数可以用于执行以下操作:


执行资源的释放,例如关闭文件、释放内存、释放网络连接等。


清理对象内部可能存在的动态分配的资源,以防止内存泄漏。


执行其他必要的清理操作以保证对象的数据和状态的一致性。


需要注意的是,如果类没有显式定义析构函数,编译器会自动生成默认的析构函数。默认析构函数执行对象的销毁操作,但不会进行任何特定的资源释放或清理操作。


析构函数的执行顺序与构造函数相反。析构函数首先调用派生类的析构函数,然后调用成员对象的析构函数,最后调用基类的析构函数。


在设计类时,若类需要管理动态分配的资源或进行其他特定的清理操作,通常需要显式定义析构函数。这确保了在对象销毁时进行必要的资源释放和清理。


四、临时对象

临时对象(Temporary objects)是在表达式求值过程中临时创建的对象,用于保存中间结果或执行特定的操作。它们没有命名,并且通常在同一行代码中即时创建和销毁。


临时对象可以出现在各种情况下,例如函数返回值、函数参数传递、运算符重载等。下面让我详细解释一些常见情况下的临时对象:


1.函数返回值:函数可以返回一个临时对象作为其返回值。例如:


class Point {

    int x, y;


public:

    Point(int xPos, int yPos) : x(xPos), y(yPos) {}


    Point operator+(const Point& other) const {

        return Point(x + other.x, y + other.y);

    }

};


Point addPoints(const Point& p1, const Point& p2) {

    return p1 + p2;  // 返回临时对象

}

在上面的示例中,addPoints 函数返回一个 Point 类型的临时对象作为两个输入点的和。


2.函数参数传递:临时对象也可以作为函数参数传递给其他函数。例如:


void printPoint(const Point& point) {

    // 打印点的坐标

}


int main() {

    printPoint(Point(3, 4));  // 传递临时对象作为参数

    return 0;

}

在这个例子中,Point(3, 4) 创建了一个临时对象,并将其作为参数传递给 printPoint 函数。


3.运算符重载:通过运算符重载,可以为类定义各种运算操作,并创建临时对象作为结果。例如:


class Integer {

    int value;


public:

    Integer(int val) : value(val) {}


    Integer operator+(const Integer& other) const {

        return Integer(value + other.value);  // 返回临时对象

    }

};


int main() {

    Integer a(5);

    Integer b(10);

    Integer c = a + b;  // 创建临时对象作为结果

    return 0;

}

在这个例子中,a + b 运算创建了一个临时对象,表示 a 和 b 相加的结果。


临时对象的生命周期通常很短暂,它们在使用后会立即销毁。它们的创建和销毁是由编译器自动处理的,无需手动管理。


临时对象的使用可以提高代码的简洁性和可读性,但需要注意的是,在使用临时对象时,确保不会出现不必要的复制操作或资源泄漏。



标签:初始化,const,函数,对象,成员,C++,构造函数
From: https://blog.51cto.com/u_16078995/7065724

相关文章

  • 【逗号你真的懂吗?】C++与JAVA中逗号的区别
    参考文章:这里一、先上结论C++中的逗号几乎可以说是随便使用,但是JAVA中的逗号就要注意了:JAVA中使用逗号(,)来分隔多条赋值语句时,只能在分隔方法的参数、定义变量时或用于for循环的表达式时使用,别的地方一律不能,只能将每条语句用分号(;)隔开。二、C++中的逗号逗号运算符和逗号表达式......
  • C++ 与 QML交互
    前言在QT中既然qml处理前端,C++处理后端,那么C++和QML是如何进行交互?将对象暴露给qmlvoidQQmlContext::setContextProperty(constQString&name,QObject*value)Setthevalueofthenamepropertyonthiscontext.QQmlContextdoesnottakeownershipofvalue.......
  • C++互斥锁
    C++11提供了4种锁机制mutex:互斥锁timed_mutex:带超时机制的互斥锁recursive_mutex:递归互斥锁recursive_imed_mutex:带超时机制的递归互斥锁!使用前需添加头文件#include<mutex>metex:使用伪代码方式mutexmtx;mtx.lock();//申请加锁。(需要加锁的资源)mtx.unlo......
  • C++通用学习速成判定
    C++的继承【C++】继承_c++继承_风继续吹TT的博客-CSDN博客#include<iostream>#include<string>usingnamespacestd;classPerson{public: voidPrint() { cout<<"_name_age_sex"<<endl; }protected: string_name; int_age; char......
  • C C++ Java python HTML/CSS/JavaScript
    C/C++是一种底层的语言,它可以直接操作内存和硬件,运行速度很快,但是也很难学习和调试,容易出错。Java是一种面向对象的语言,它可以跨平台运行,有很多成熟的框架和库,适合做大型的企业级应用,但是也很繁琐和冗长,需要写很多代码。Python是一种高级的语言,它可以用简洁的语法来实现复杂的功能......
  • C++系列三:QT初识
    目录前言QT介绍前言开发环境,挺折腾人,一波三折。参考链接:C语言中文网、QT快速入门官方文档QT介绍跨平台的GUI。主要用于桌面程序开发和嵌入式开发。目前Qt的开源授权有两种,一种是GPL授权,另一种是LGPL授权QML主要用于手机移动应用程序Windows下的GUI解决方案......
  • C++系列二:STL教程-迭代器
    目录前言迭代器前言……。迭代器//它可以是需要的任意类型,通过迭代器可以指向容器中的某个元素,如果需要,还可以对该元素进行读/写操作。常用的迭代器按功能强弱分为输入迭代器、输出迭代器、前向迭代器、双向迭代器、随机访问迭代器5种。输入迭代器和输出迭代器比较特殊,它......
  • 浅析C++gnu pbds库
    pbds俗称平板电视,__gnu_pbds自带了封装好了的平衡树、字典树、hash数据结构,速度快过\(STL\)Ⅰ.引入想要使用\(pbds\),必须先要添加头文件,\(pbds\)并不属于bits/stdc++.h的一部分,所以也只能在\(g++\Mingw64\)的环境下食用。以下是头文件:#include<bits/extc++.h>以下是命名空......
  • RichEdit 选中文本的高亮显示 VC++
    RichEdit控件失去焦点后,选中文本不再高亮显示。有两种方法可以改变,使得控件失去焦点仍然保持高亮:方法一:创建控件时设置ES_NOHIDESEL风格m_hWndREdit=CreateWindow(_T("RichEdit20W"),NULL,//RICHEDIT_CLASSRichEdit20ARichEdit20WWS_CHILD|WS_VISIBLE|ES......
  • C++实现一键关闭桌面
    方法一:C++关闭桌面,explorer.exe#include<Windows.h>#include<TlHelp32.h>#include"resource.h"#pragmawarning(disable:4996)voidtaskkill(constchar*name){ HANDLEinfo_handle=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);//拍摄系统中所有进......