目录
类的引入
C语言结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。比如:
用C语言方式实现的栈,队列等等,结构体中只能定义变量;现在以C++方式实现,struct中也可以定义函数。
类的定义
class className
{
// 类体:由成员函数和成员变量组成
}; // 一定要注意后面的分号
class为定义类的关键字,ClassName为类的名字,{}中为类的主体,注意类定义结束时后面分
号不能省略。
类体中内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的方法或者
成员函数
类的两种定义方式:
1. 声明和定义全部放在类体中,需注意:成员函数如果在类中定义,编译器可能会将其当成内
联函数处理。
2. 类声明放在.h文件中,成员函数定义放在.cpp文件中,注意:成员函数名前需要加类名::
一般情况下,更期望采用第二种方式,在工作中 ,也大都喜欢第二种。
成员变量命名规则的建议:
class Date
{
public:
void Init(int year)
{
// 这里的year到底是成员变量,还是函数形参?
year = year;
}
private:
int year;
};
// 其实我们都能知道=右边是函数形参,左边是成员变量,为了加以区分,所以一般都建议这样
class Date
{
public:
void Init(int year)
{
_year = year;
}
private:
int _year;
};
// 或者这样
class Date
{
public:
void Init(int year)
{
mYear = year;
}
private:
int mYear;//别的方式也可,为了加以区分,一般加前缀或者后缀。
类的访问限定符和封装
C++实现封装的方式:用类将对象的属性与方法结合在一块,让对象更加完善,通过访问权限选
择性的将其接口提供给外部的用户使用。
【访问限定符说明】
1. public修饰的成员在类外可以直接被访问
2. protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)
3. 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止
4. 如果后面没有访问限定符,作用域就到 } 即类结束。
5. class的默认访问权限为private,struct为public(因为struct要兼容C)
注意:访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别
有一道相关的面试题:
问题:C++中struct和class的区别是什么?
解答:C++需要兼容C语言,所以C++中struct可以当成结构体使用。另外C++中struct还可以用来
定义类。和class定义类是一样的,区别是struct定义的类默认访问权限是public,class定义的类
默认访问权限是private。
class Date
{
public:
void Init(int year,int month,int day){
-year=year;
-month=month;
-day=day;
}
int -year;int -month;
int -day;//这里只是声明,还未开辟空间,举个例子,相当于盖房子时设计的图纸
};int main()
{
//类对象实例化---开空间,此时相当于依照设计图盖房子
Date a;
Date b;//一个类可以实例化出许多对象,就相当于一个图纸可以盖许多房子。
Date.-year=1;
Date::-month=1;
//这两种是错误的,因为没有进行实例化,就相当于盖房子时那些材料不可能建到图纸里面。
}
类大小的计算:
相当于C语言的struct,要考虑内存对齐
由此可见,成员变量在对象中,而成员函数却不在对象中。
事实上,每一次实例化都开辟单独的空间,成员变量不一样,需要单独存储,但是共用同一个函数,存在于代码段中,调用成员函数不在对象中找,在代码段中找,相当于一整个小区要共用一个篮球场一样,所以算一个对象的大小,只考虑成员变量。
// 类中既有成员变量,又有成员函数
class A1 {
public:
void f1(){}
private:
int _a;
};// 类中仅有成员函数
class A2 {
public:
void f2() {}
};
// 类中什么都没有---空类
class A3
{};
经过上面的解释,可以知道sizeof(A1)=4;而sizeof(A2)和sizeof(A3)不等于0而等于1,这是因为1byte并不存有效数据,表示一个占位,标识对象被实例化定义出了。
this指针
在调用成员成员函数的时候,如果存在多个对象,如何分辨出是哪个对象在调用成员函数呢,这就得提到this指针了。
C++中通过引入this指针解决该问题,即:C++编译器给每个“非静态的成员函数“增加了一个隐藏
的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有“成员变量”
的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编
译器自动完成。
实际上,编译器在处理函数时,编译器内部是这样的
#include<iostream>
using namespace std;
class Date
{
public:
void Init(Date *this,int year, int month, int day)//编译器自己形成,自己不能写{
this->_year = year;
this-> _month = month;
this->_day = day;//自己可以加上,一般不建议
}
int _year;
int _month;
int _day;
};
int main()
{
Date d1;
Date d2;
d1.Init(&d1,2003,2,2);d2.Init(&d2,2004,3,3);//编译器自己调用,不能手动添加
}
this指针的特性
1. this指针的类型:类类型* const,即成员函数中,不能给this指针赋值。
2. 只能在“成员函数”的内部使用
3. this指针本质上是“成员函数”的形参,当对象调用成员函数时,将对象地址作为实参传递给
this形参。所以对象中不存储this指针。
4. this指针是“成员函数”第一个隐含的指针形参,存在于栈,一般情况由编译器通过ecx寄存器自动传
递,不需要用户传递
this指针的难点之空指针问题
学过指针都知道,空指针不能解引用,但是存在“->”不一定就是空指针的解引用 ,上面的代码并没有错误而是正常运行。
调用Init函数会发生错误