【C++】类和对象(上)

目录

一、面向对象和面向过程的基本认识

二、类的定义

三、类的特点

1.类的三大特点:封装、继承、多态

2.类域

四、成员函数

五、this指针

1.this指针的引出

2.this指针的特性

六、总结


一、面向对象和面向过程的基本认识

我们都知道,C++是兼容C语言的,C语言是一门面向过程的编程语言,而C++一般用于面对对象编程。那么,面对对象和面对过程编程有何不同点呢?

1.面向过程编程简单来说就是通过分析解决问题的步骤,然后利用函数来完成解题步骤的详细设计,通过调用函数来解决问题。

2.面向对象编程简单来说就是通过分析问题面临的对象,将对象进行分组设计,将解决问题的办法分解成若干对象的问题解决。

3.上述区别可能会难以理解,其实我们可以将面向对象和面向过程编程联想成一个具体的实例,比如:洗衣服。

面向过程:洗衣服的步骤可以分为以下部分:

面向对象:洗衣服的相关对象有:盆子、人等。具体对象之间的联系和洗衣服的具体步骤不需要了解,会在对象的定义解决。

二、类的定义

C语言结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。

C++中类的定义可以用structclass关键字来定义。

区别:strcut定义的类中的成员变量默认是公有的(为了兼容C语言),而class定义的类中的成员 

          变量默认是私有的。

但是在C++中,更加倾向于用class来定义类(类的封装性):

class className

{
    // 类体:由成员函数和成员变量组成

}; // 一定要注意后面的分号

类体由成员函数和成员变量组成,成员函数又叫类的方法,一般都是共有的(public);成员变量又叫类的属性,有三种分类:private、protected、public,分类的根据是成员变量访问的权限不同(后续的博客中会有介绍)。

注意:1.类定义(声明)时不开辟空间,只有实例化(定义类对象)时才会开辟空间。(可以类比成画                  图纸和建房子,画图纸不会实际占用土地空间,只有按图纸实际盖房子时才会占用空间)

           2.因为类的成员变量是属于每个类对象的私有部分,类的成员函数是属于所有对象的,是                  一段公共区域的代码段,所以类的大小是成员变量的大小(要考虑内存对齐),其计算方法和                C语言中的计算结构体大小的方法相同。

           3.空类(没有成员变量的类)的对象的大小是1byte,不存储数据,起一个标志作用(占位                符),标记类对象成功创建。

三、类的特点

1.类的三大特点:封装、继承、多态

在类和对象阶段,主要是研究类的封装特性,那什么是封装呢?
封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来
和对象进行交互。

封装本质上是一种管理,让用户更方便使用类,并且不能随意访问或更改类的属性,对类的内部结构起到了一定的保护作用。在C++语言中实现封装,可以通过类将数据以及操作数据的方法进行有机结合,通过访问权限来隐藏对象内部实现细节,控制哪些方法可以在类外部直接被使用。

(继承和多态在后续的博客中会有说明)

2.类域

类定义了一个新的作用域,类的所有成员都在类的作用域中。在类体外定义成员时,需要使用 ::
作用域操作符指明成员属于哪个类域。
例如:

//类域
class Date
{
public:
	Date(int year,int month,int day);
	void Print();
private:
	int _year;
	int _month;
	int _day;
};

Date::Date(int year, int month, int day)
{
	_year = year;
	_month = month;
	_day = day;
}

void Date::Print()
{
	cout << _year << '-' << _month << '-' << _day << endl;
}

int main()
{
	Date d1(2023, 2, 12);
	d1.Print();

	return 0;
}

上述程序的运行结果:2023-2-12

程序中的::是作用域操作符,在类外定义成员函数和通过类名调用成员函数是都要用到。 

类域是一块新定义的作用域,类内的成员变量和成员函数都属于这个类,他们的作用域就是这个类域。

四、成员函数

类的两种定义方式:

1. 声明和定义全部放在类体中,需注意:成员函数如果在类中定义,编译器可能会将其当成内联函数处理。

2. 类声明放在.h文件中,成员函数定义放在.cpp文件中,注意:成员函数名前需要加类名::,例如:Date::Date(){}

五、this指针

this指针就是类对象的地址。

1.this指针的引出

以日期类Date为例:

class Date
{
public:
    void Init(int year, int month, int day)
    {
        _year = year;
        _month = month;
        _day = day;
    }

    void Print()
    {
        cout <<_year<< "-" <<_month << "-"<< _day <<endl;
    }

private:
    int _year;//年
    int _month;//月
    int _day;//日
};

int main()
{
    Date d1, d2;
    d1.Init(2022,1,11);
    d2.Init(2022, 1, 12);
    d1.Print();
    d2.Print();

    return 0;
}

类的成员函数是所有的类对象所共有的,但是每个类对象调用成员函数的时候,都是操作的自己的成员变量,但是类的成员函数中没有对不同类对象的区分,这是怎么做到的呢?

对于上述类,有这样的一个问题:

Date类中有 Init 与 Print 两个成员函数,函数体中没有关于不同对象的区分,那当d1调用 Init 函数时,该函数是如何知道应该设置d1对象,而不是设置d2对象呢?

C++中通过引入this指针解决该问题,即:C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有“成员变量”的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。

综上,this指针的根本目的是为了多个类对象调用成员函数时,成员函数可以区分应该操作的类对象。

2.this指针的特性

①成员函数的this指针不可修改,其数据类型为 类类型* const,例如:Date* const。

②this指针是编译器加给非静态成员函数的隐藏形参(只在成员函数内部使用),当对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针

③this指针是“成员函数”第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递。

④this指针存储在栈上,成员函数调用结束后栈帧销毁,this指针还在,所以当函数返回值是类类型的时候,可以使用引用,减少拷贝构造的调用。(拷贝构造函数在后面的博客中会介绍)

相关的例题:

// 1.下面程序编译运行结果是? A、编译报错 B、运行崩溃 C、正常运行

class A
{
public:
    void Print()
    {

        cout << "Print()" << endl;
    }

private:
    int _a;
};

int main()

{
    A* p = nullptr;
    p->Print();

    return 0;
}

上述程序运行的结果是正常运行

// 2.下面程序编译运行结果是? A、编译报错 B、运行崩溃 C、正常运行

class A
{
public:
    void PrintA()
    {
        cout<<_a<<endl;
    }

private:
    int _a;
};

int main()

{
    A* p = nullptr;
    p->PrintA();

    return 0;
}

上述程序的运行的结果是运行崩溃

为什么?

将nullptr赋值给类对象指针后,并不影响*()和->的使用,nullptr是在调用类的成员函数时传给了成员函数的隐藏形参this指针,如果调用的成员函数的函数体没有对this指针进行*()和->的操作,则不会影响程序的正常运行。

这个问题的关键是理解nullptr的传递。两段代码中的p->PrintA()语句都没有对空指针进行->操作,而是通过地址为p的类对象调用了类域里面的成员函数Print(),并将nullptr赋值给this指针。两段程序运行结果不同是因为调用的成员函数的函数体,前者为对nullptr作任何操作,而后者访问了其成员变量,对nullptr进行了->操作,从而导致第二段程序执行时崩溃。

六、总结

本文主要介绍了对C++中类的初步认识以及相关的一些基本知识,剩下的内容会在接下来的博客中进行具体介绍。希望大家多多支持,也希望各位大佬能指点一二。

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值