C++:类与对象

这篇具有很好参考价值的文章主要介绍了C++:类与对象。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

类的定义

类是对一组具有共同属性特征和行为特征的对象的抽象,它可将相关数据和这些数据的操作(函数)组合在一起。

类定义格式

类定义格式:

class 类名
{
public:
	数据成员或成员函数
protected:
	数据成员或成员函数
private:
	数据成员或成员函数
};
  1. 类名

    class是声明类的关键字,类名是标识符,且在其作用域内必须是唯一的。

    注:C++规定,标识符以字母(大小写均可,但区分大小写)或下划线开头,后面跟0或多个有字母、数字字符或下划线组成的字符串。

  2. 成员说明

    类包括两类成员:一类是代表对象属性的数据成员;另一类是实现对象行为的成员函数。成员函数的定义不仅仅可以与声明同时在类内完成,也可以在类外完成。若在类外完成,则需用作用域‘::“符号。

  3. 访问权符

    访问权符也成为访问权限或访问控制符,它规定类中说明成员的访问属性。

    c++共提供三种不同的访问权符:public、protected、private。

    public(共有类型):声明该成员为公有成员。表示该成员哭可以被和该类对象处在同一作用域内的任何函数使用。一般将成员函数声明为共有的访问控制。

    protected(保护类型):声明该成员为保护成员。表示该成员只能被所在类中的成员函数及该类的友元函数使用。

    private(私有类型):声明该成员为私有成员。表示该成员只能被所在类中的成员函数和该类的友元函数使用。

声明一个图书类:

class Book{
public://访问权限,共有成员
    void inpub();//行为,成员函数的原型声明
    void print();//行为,成员函数的原型声明
private://访问权限,私有成员
    char title[12];//属性,数据成员
    char author[10];
    char publish[30];
    float price;
};

【注】:

  1. 类型命中的public、protected、private关键字可以按任意顺序出现,但为了让程序更加整洁,应将共有成员、保护成员和私有成员归类存放。默认的访问权限是私有类型。
  2. 对于一个具体的类,它们三个并不一定都要有,但至少需要有一个。
  3. 数据成员可以是任何数据类型,但不能用自动(auto)寄存器(register)外部(extern)类型进行说明。
  4. 类是一种广义的数据类型,系统并不会为其分配内存空间,所以不能在类声明中给数据成员赋初始值。
  5. 类的主体是包括在一对花括号中的,它的定义必须以”;“结束。

成员函数的定义

为了实现对象的行为,将一些相关的语句组织在一起,并给他们注明相应的名称,从而形成一些相对独立且方便管理和阅读的小块程序,每个小块程序都能描述一个完整的行为,这个小块程序就构成了成员函数。

成员函数的定义有两种形式:第一种是对于代码较少的成员函数,可以直接在类中定义;第二种是对于代码较多的成员函数,通常只在类中进行函数原型声明,在类外对函数进行定义,这个成员函数的定义格式如下:

返回类型  类名::函数名(参数表){//函数体}

例如上面的成员函数的定义:

void Book::inpub() {
    cin >> title >> author >> publish >> price;
}

void Book::print() {
    cout << title << " " << author << " " << publish << " " << price << endl;
}

对象的定义于使用

在C++中声明类表示定义了一种新的数据类型,只有定义了类的对象,才真正创建了这种数据类型的物理实体。对象是封装了数据结构及可以施加在这些数据结构上操作的封装体。对象是类的实际变量,一个具体的对象是类的一个实例。

对象的定义

有两种方法可以定义对象:

  1. 在声明类的同时,直接定义对象。

    class Book{
    public://访问权限,共有成员
        void input();//行为,成员函数的原型声明
        void print();//行为,成员函数的原型声明
    private://访问权限,私有成员
        char title[12];//属性,数据成员
        char author[10];
        char publish[30];
        float price;
    }b1;//定义b1是类Book的对象
    
  2. 先声明类,然后使用时在定义对象,定义格式于一般变量定义格式相同:类名 对象名列表;

对象的使用

使用对象就是像对象发送信息,请求执行其某个方法,从而向外界提供要求的服务,格式:

对象名.成员函数名(实参表);

Book b1;
b1.input();//通过b1执行输入操作
b1.print();//通过b1执行输出操作

对象的赋值

同类型的变量可以利用赋值运算符”=“进行赋值,对于同类型的对象也同样适用。这种赋值默认通过成员复制进行。当对象进行赋值时,对象的每个成员逐一复制给另一个对象的同一个成员。

例如平面上点的赋值。


#include "iostream"
#include "iomanip"

using namespace std;
class Point{
public:
    void SetPoint(int a, int b);
    void Print(){
        cout << "x=" << x << setw(5) << "y=" << y << endl;
    }
private:
    int x, y;
};
void Point::SetPoint(int a, int b) {
    x = a;
    y = b;
}
int main(){
    Point p1, p2;
    p1.SetPoint(1, 2);
    cout << "p1:" << endl;
    p1.Print();
    cout << "p2:" << endl;
    p2.Print();
    p2 = p1;
    cout << "p2=p1:" << endl;
    p2.Print();
    return 0;
}

运行结果:

p1:
x=1   y=2
p2:
x=-873984000   y=32759
p2=p1:
x=1   y=2

【注】:

  1. 在使用对象赋值语句进行赋值时,两个对象的类型必须相同,但赋值兼容规则除外。
  2. 两个对象间的赋值,仅使对象中的数据相同,二两个对象任然时彼此独立的,各自有自己的内存空间。
  3. 若类中存在指针,则不能简单地将一个对象的值赋值给另一个对象,否则会出错。

构造函数和析构函数

对对象进行初始化的一种方法就是编写初始化函数,然而很多用户在解决问题时,往往会忽略这些函数,以至于给朝鲜带来了隐患。为了方便对象的初始化工作,C++提供了两个特殊的成员函数,即构造函数和析构函数。构造函数的功能时在创建对象时,给数据成员赋初值,即对象的初始化。析构函数的功能时释放一个对象,在对象删除之前,用它来做一些内存释放等清理工作,它的功能于构造函数正好相反。

构造函数

在类的定义中不能直接对数据成员进行初始化,要想对对象中的数据成员进行初始化,一种方法是手动调用成员函数来完成初始化,但这会给程序员带来很大的负担。另一种就是使用构造函数。它是一种特殊的成员函数,是为对象分配空间、初始化,并且在对象创建时会被系统自动执行。

定义构造函数原型的格式:类名(形参列表);

在类外定义构造函数的格式:类名::类名(形参列表){//函数语句;}

构造函数特点如下:

  1. 构造函数的名字必须于类名相同,否则系统会将它当作一般的成员函数来处理。
  2. 构造函数可以用任意类型的参数,但是没有返回值类型,也不能指定void类型。
  3. 定义对象时,系统会自动地调用构造函数。
  4. 通常构造函数被定义在共有部分。
  5. 若没有定义构造函数,系统会自动生成一个默认的构造函数,它只负责对象的创建,不带任何参数,只能给对象开辟一个存储空间,数据成员的值也是随机的。
  6. 构造函数可以重载。

例如平面上点的赋值

#include "iostream"
#include "iomanip"

using namespace std;
class Point{
public:
    Point(int a, int b){
        x = a;
        y = b;
    }
    void Print(){
        cout << "x=" << x << setw(5) << "y=" << y << endl;
    }
private:
    int x, y;
};

int main(){
    Point p1(1,2);
    cout << "p1:" << endl;
    p1.Print();
    return 0;
}

【注】:

  1. 构造函数不能不带参数,例如:

    class Point{
    public:
    	Point(){x=0;y=0}
    	//...
    private:
    	int x, y;
    }
    
  2. 构造函数也可以采用构造初始化表对数据成员进行初始化,例如

    class Point{
    public:
    	Point(int a, int b):x(a),y(b){}
    	//构造函数初始化表对数据成员进行初始化
    	//...
    private:
    	int x, y;
    }
    
  3. 若数据成员时数组,则应该在构造函数种使用相关语句进行初始化,例如:

    class Point{
    public:
    	Point(char a[], int b):y(b){strcpy(x, strlen(a) + 1, a);}
    	//...
    private:
    	char x[10];
    	int  y;
    }
    

析构函数

析构函数时一种特殊的成员函数,当删除对象时就会被调用。也就是说,在对象的生命周期即将结束时,由系统自动调用,其目的是在系统回收对象内存之前执行结束清理工作,以便内存可被重新用于保存新对象。

定义析构函数的格式为:~类名();

析构函数的特点为:

  1. 析构函数名是由“~”和类名组成的。
  2. 析构函数没有参数,也没有返回值,而且不能重载。
  3. 通常析构函数被定义在共有部分,并有系统自动调用。
  4. 一个类中有且仅有一个析构函数,用为public

【注】:

  1. 析构函数的功能是释放对象所占用的内存空间,它在对象生命周期结束前由系统自动调动。
  2. 析构函数和构造函数两者的调用次序相反,即最先构造的对象最后被析构,最后构造的对象最先被析构
  3. 析构函数除了在显示撤销对象时,系统会自动调用外,函数结束时,函数内对象的析构函数也会被自动调用

内存的动态分配

用户存储区空间分为三部分:程序区(代码区)、静态存储区(数据区)和动态存储区(栈区和堆区)。代码区存放程序代码,程序有奴性前就可以分配存储空间。数据区存放常量、静态变量、全局变量等。栈区存放局部变量、函数参数、函数返回值和临时变量等。堆区是程序空间种存在的一些空闲存储单元。在堆中创建的数据对象称为堆对象。当创建对象时,堆中的一些存储单元从未分配状态变为已分配状态;当删除所创建的堆对象时,这些存储单元从已分配状态又变为未分配状态。当堆对象不再使用时,应给予删除,回收所占用的动态内存。C++中使用new和delete来实现在堆内存中进行数据的动态分配和释放。

运算符new

new功能时实现内存的动态分配。在程序运行过程中申请和释放的存储单元称为堆对象。申请和释放的过程称为建立和删除堆对象。

new的使用格式:

指针变量=new T;//T表示数据类型名
指针变量=new T(初值列表);
指针变量=new T[元素个数];

用new创建堆对象的格式:类名 *指针名 = new 类名([构造函数参数]);

【注】:

  1. new返回一个指定的合法数据类型内存空间的首地址(指针),若分配失败,则返回一个空指针。
  2. new不能对动态分配的数组存储去进行初始化。
  3. 用new分配的空间,使用结束后只能用delete来释放,否则这部分空间将不会被回收,从而造成内存泄漏。

运算符delete

delete用来释放动态变量或动态数组所占的内存空间,其格式为:

delete 指针变量名;
delete []指针变量名;

动态创建类Point的对象:

#include "iostream"
using namespace std;
class Point{
public:
    Point(int a, int b){
        x = a;
        y = b;
        cout << "inside constructor" << endl;
    }
    ~Point(){
        cout << "inside destructor" << endl;
    }
private:
    int x, y;
};

int main(){
    Point *p = new Point(1, 2);
    delete p;
    return 0;
}

对象数组和数组指针

对象数组

数组的元素既可以时基本数据类型的数据,也可以是用户自定义数据类型的数据。对象数组是指每个数组元素都是对象的数组。对象数组的元素是对象,它不仅具有数据成员,而且还有成员函数。

声明对象数组的格式为:类名 数组名[下标表达式];

与基本类型的数组一样,在使用对象数组时也只能引用单个数组元素,通过对象可以方位其公有成员。对象数组的引用格式为:数组名[下标].成员函数

例如类Point

#include "iostream"
using namespace std;
class Point{
public:
    Point(int a, int b){
        x = a;
        y = b;
    }
    void Print(){
        cout << "(" << x << "," << y << ")" << endl;
    }
private:
    int x, y;
};

int main(){
    Point ob[3] = {Point(1,2),Point(3,4), Point(5, 6)};
    for(int i = 0; i < 3; i++){
        cout << "第 " << i + 1 << " 个点的坐标为:";
        ob[i].Print();
    }
    return 0;
}

运行结果:

1 个点的坐标为:(1,2)2 个点的坐标为:(3,4)3 个点的坐标为:(5,6)

对象指针

访问一个对象既可以通过对象名访问,也可以通过对象地址访问。对象指针就是用于存放对象地址的变量,它遵循一般变量指针的各种规则,对象指针的格式为:类名 *对象指针名;

与用对象名来访问对象成员一样,使用对象指针也可以访问对象的成员,格式:对象指针名 − > -> >成员名

例如,类Point

#include "iostream"
using namespace std;
class Point{
public:
    Point(int a, int b){
        x = a;
        y = b;
    }
    void Print(){
        cout << "(" << x << "," << y << ")" << endl;
    }
private:
    int x, y;
};

int main(){
    Point ob[3] = {Point(1,2),Point(3,4), Point(5, 6)};
    Point *p =ob;
    for(int i = 0; p < ob + 3; p++, i++){
        cout << "第 " << i + 1 << " 个点的坐标为:";
        p->Print();
    }
    return 0;
}

运行结果:

1 个点的坐标为:(1,2)2 个点的坐标为:(3,4)3 个点的坐标为:(5,6)

自引用指针this

this指针,即自引用指针,每当对象调用成员函数时,系统就将该对象的地址赋给this指针,这是编译器将根据this指针所指向的对象来确定应该引用哪个对象的数据成员。通常this指针在系统中时隐含地存在。

使用this指针应该注意:文章来源地址https://www.toymoban.com/news/detail-651724.html

  1. this指针是一个const指针,不能再程序中修改或给它赋值
  2. this指针是一个局部数据,其作用域仅在一个对象的内部
  3. 静态成员函数不属于任何一个对象,且没有this指针

到了这里,关于C++:类与对象的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++】类与对象(上)

    之前的文章中讲解了,什么是类、类的实例化,以及封装的意义,若仍有不理解的部分可以移步上一篇文章  【C++】类与对象(引入) 目录 系列文章 1.默认成员函数 2.构造函数 2.1定义 2.2特性 2.2.1重载构造函数 2.2.2与缺省参数混合使用 2.2.3默认构造函数 3.析构函数 3.1定义

    2023年04月15日
    浏览(27)
  • 【C++】——类与对象(下)

    本文是C++类与对象部分最后一篇文章,类与对象的重点是类与对象(中),本文主要是补充类与对象的剩余知识点及收尾。 在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。 构造函数体中的语句只能将其称为赋初值,而不能称作初始化。

    2024年02月06日
    浏览(25)
  • C++ 类与对象(上)

    目录 本节目标  1.面向过程和面向对象初步认识  2.类的引入  3.类的定义 4.类的访问限定符及封装 4.1 访问限定符 4.2 封装 5. 类的作用域 6. 类的实例化  7.类对象模型 7.1 如何计算类对象的大小 7.2 类对象的存储方式猜测 7.3 结构体内存对齐规则  8.this指针 8.1 this指针的引出

    2024年02月19日
    浏览(33)
  • 【C++】——类与对象(上)

    今天我们来学习C++初期最重要的知识点,类与对象,因为类与对象涉及的知识太多,所以我将分为上中下三个部分来为大家讲解类与对象。 C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。 C++是基于面向对象的,关注的是对象,将一

    2024年02月02日
    浏览(31)
  • [C++]类与对象下篇

    目录 类与对象下篇::                             1.再谈构造函数                             2.static成员                             3.友元                             4.内部类                             5.匿名对象                             6.拷贝

    2023年04月25日
    浏览(32)
  • 【C++】类与对象(中)

    目录 1. 类的6个默认成员函数 2. 构造函数 2.1 概念 2.2 特性 3. 析构函数 3.1 概念 3.2 特性 4. 拷贝构造函数 4.1 概念 4.2 特征 5. 赋值运算符重载 5.1 运算符重载 5.2 赋值运算符重载 5.3 前置++和后置++重载 6. const成员 7. 取地址及const取地址操作符重载 如果一个类中什么成员都没有,

    2024年02月05日
    浏览(34)
  • C++:类与对象

    类是对一组具有共同属性特征和行为特征的对象的抽象,它可将相关数据和这些数据的操作(函数)组合在一起。 类定义格式: 类名 : class是声明类的,类名是标识符,且在其作用域内必须是唯一的。 注:C++规定,标识符以字母(大小写均可,但区分大小写)或下划

    2024年02月12日
    浏览(29)
  • 【C++】类与对象(下)

      若想了解什么是类、封装的意义可以移步  【C++】类与对象(引入)   若对六大成员函数或const成员函数有疑问的这篇文章可能可以帮到你  【C++】类与对象(上) 目录 系列文章 前言 1.初始化列表 1.1概念 1.2特性  1.2.1必须使用初始化列表的情况 1.2.2初始化的顺序 2.expli

    2023年04月14日
    浏览(23)
  • c++类与对象

    🐶博主主页: @ᰔᩚ. 一怀明月ꦿ  ❤️‍🔥 专栏系列: 线性代数,C初学者入门训练,题解C,C的使用文章 🔥 座右铭: “不要等到什么都没有了,才下定决心去做” 🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀  目录 🐰类与对象 🌸

    2023年04月08日
    浏览(31)
  • C++ 类与对象(下)

    目录 1. 再谈构造函数 1.1 构造函数体赋值  1.2 初始化列表  1.3 explicit  2. static成员 2.1 概念 2.2 特性  3.友元 3.1友元函数   3.2 友元类 4. 内部类 5.匿名对象  6.拷贝对象时的一些编译器优化  7. 再次理解类和对象 1. 再谈构造函数 2. Static成员 3. 友元 4. 内部类 5.匿名对象

    2024年02月19日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包