类和对象(上)—— 语法初识

目录

1.类的引入和定义

2.类的访问限定符和封装

3.类的作用域

4.类的实例化及其大小

5.this指针


1.类的引入和定义

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

  如下示例:

  上面结构体的定义,在C++中更喜欢用class关键字来代替struct ,而且把这种定义叫做 "类",它的定义方式如下: 

  类体中内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的方法或者 成员函数。 

  并且建议:成员变量的命名一般都是加个前缀或者后缀标识区分,比如:int _year; int _age等。否则可能出现混淆歧义的情况,如下示例:

  除了要注意命名规范外,struct和class在使用上也有区别,如下: 

   要弄清楚示例中的错误原因,就得接着往下学习新的概念了。

2.类的访问限定符和封装

  封装是面向对象的三大特性之一,它是指:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。

  比如:对于计算机这样复杂的设备,提供给用户的就只有开关机键、通过键盘输入,显示器,USB插孔等,让用户和计算机进行交互,完成日常事务。但实际上计算机真正工作的却是CPU、显卡、内存等一些硬件元件。

  对于计算机使用者而言,不用关心内部核心部件,比如主板上线路是如何布局的,CPU内部是如 何设计的等,用户只需要知道,怎么开机、怎么通过键盘和鼠标与计算机进行交互即可。因此计 算机厂商在出厂时,在外部套上壳子,将内部实现细节隐藏起来,仅仅对外提供开关机、鼠标以 及键盘插孔等,让用户可以与计算机进行交互即可,这就是一种封装。

  在C++语言中实现封装,可以通过类将数据以及操作数据的方法进行有机结合,通过访问权限来 隐藏对象内部实现细节,控制哪些方法可以在类外部直接被使用。 

  访问权限涉及到的访问限定符分别是:public(公有),protected(保护),private(私有)

  说明:1. public修饰的成员在类外可以直接被访问

             2. protected和private修饰的成员在类外不能直接被访问(当前阶段我们认为它们没有区别)

             3. 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止

             4. 如果后面没有访问限定符,作用域就到 } 即类结束

             5. class的默认访问权限为private,struct为public(因为struct要兼容C)

  (一般而言:类的成员变量设为私有,需要对外提供的接口,即成员函数,设为公有。这起到保护数据的效果) 

  如下示例:

3.类的作用域

  类定义了一个新的作用域,类的所有成员都在类的作用域中。在类体外定义成员时(成员函数的声明和定义分离时),需要使用 :: 作用域操作符指明成员属于哪个类域。 

  如下示例:

  需要注意的是:在类体内实现的函数默认是内联。 

4.类的实例化及其大小

  用类这个类型创建对象的过程,称为类的实例化 。

  我们在上面的示例当中其实已经多次用类实例化对象了,所以此处不再演示,这里着重讲解需要注意的一些概念。

  首先,类是对对象进行描述的,是一个模型一样的东西,限定了类有哪些成员,就像现实中使用建筑设计图建造出房子,类就像是设计图,只设计出需要什么东西,但是并没有实体的建筑存在,所以:定义出一个类并没有分配实际的内存空间来存储它,只有实例化出类的对象才会开辟内存。

  其次一个类可以实例化出多个对象,并且每个对象所开辟的内存只存储成员变量,成员函数存放在公共的代码段,如下示例:

  这也不难理解,就像小区一样,每户人家的属性都是不同的,需要独立的空间,但是小区的绿化带,走道,娱乐锻炼设施等公共的东西只需要一份。那么对于类和对象来说也是一样的道理,同一个类实例化出的对象只有数据的属性不同,操作数据的方法都是一样的,一份就够了。

  接下来,我们就验证一下: 

  结论:一个类的大小,实际就是该类中”成员变量”之和(注意内存对齐),空类比较特殊,编译器给了空类一个字节来唯一标识这个类的对象。 

5.this指针

  先看示例:

  对于上述的示例结果,你有没有思考过这样的问题:Date类中有 Init 与 Print 两个成员函数,它们在公共代码区,并且函数体中没有关于不同对象的区分,那当d1调用 Init函数时,该函数是如何知道应该设置d1对象,而不是设置d2对象呢? 

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

  this指针的原型是:类类型* const this

  那么上面问题的答案就是:

  弄清楚了上述的内容,接着来看看下面两段代码的编译运行结果是什么?

  A.编译报错  B.运行崩溃  C.正常运行

//第一段代码
class A
{
public:
	void Print()
	{
		cout << "Print()" << endl;
	}
private:
	int _a;
};

int main()
{
	A* p = nullptr;
	p->Print();
	return 0;
}

//第二段代码
class B
{ 
public:
    void PrintB() 
   {
        cout<<_b<<endl;
   }
private:
 int _b;
};
int main()
{
    B* p = nullptr;
    p->PrintB();
    return 0;
}

  正确答案是:第一段代码:C.正常运行

                       第二段代码:B.运行崩溃

  怎么样,你做对了吗?

  我们来调试看一下:

     本篇分享到这就结束了,如果对你有所帮助就是对小编最大的鼓励,如果可以的话,点赞+收藏并分享给你的小伙伴一起学习,当然也欢迎你在评论区留下你的足迹,这将是支持小编不懈创作的动力!

  关注小编,持续更新,下篇继续《类和对象(中)—— 类的6个默认成员函数》。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一般清意味……

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值