目录
一、面向对象和面向过程
面向对象就是大部分重心都关注对对象的操作,而不关心具体函数的相关实现的细节等等;而面向过程就是没那么关注对对象的操作,但大部分关注具体函数的实现的细节。
二、类
1、类的概念
C++ 把 C 里的结构体升级成了类。在 C 中,结构体只能定义变量;但在 C++ 中,类不仅可以定义变量,还可以定义函数。
struct Student
{
void SetStudentInfo(const char* name, const char* gender, int age)
{
strcpy(_name, name);
strcpy(_gender, gender);
_age = age;
}
void PrintStudentInfo()
{
cout<<_name<<" "<<_gender<<" "<<_age<<endl;
}
char _name[20];
char _gender[3];
int _age;
};
2、类的访问限定符及封装
(1)访问限定符
在 C++ 中只有三种访问限定符:public(公共)、private(私人)、protected(保护)。这里由于这只是 C++ 入门,因此先粗浅地认为 private 和 protected 都是“私有”的意思吧 。
a. public
从中文翻译就不难看出来,这个限定符的限定范围是不限定的,是允许在类域外被访问的。
b. protected、private
从中文翻译也不难看出,这两个限定符是不允许在类域外被访问的。但是可以在类域内被访问!
附:C++ 中 struct 和 class 的区别?(重点)
答:struct 的默认访问限定符是 public ,但 class 的默认访问限定限定符是 private。
(2)封装
什么是封装呢?在 C++ 中,为了避免一些语法不规范的代码风格,一般把变量的声明、属性等等用 private 封起来,只开放一些函数的实现或函数声明来给类域外的变量访问。这样不仅可以不用关注相关函数的实现细节,还可以更加关注于对对象本身的操作。
class Date
{
public:
void PrintDate(int year, int month, int day);
private:
int _year;
int _month;
int _day;
};
void Date::PrintDate(int year, int month, int day)
{
cout << year << month << day << endl;
}
(3)类中成员声明规则
a. 成员变量的声明
成员变量的声明和 C 语言的结构体一样,但由于 C++ 面向对象,因此成员变量一般都用 private 封装起来。
b. 成员函数的声明
这里有两种方法。
第一种:直接在类域里定义
这种就直接像普通函数定义就行了。
class Stack
{
public:
void STInit()
{
//...
}
void STPush(int x)
{
//...
}
int STTop()
{
//...
}
private:
int capacity;
int size;
int *a;
};
第二种:先在类域里声明,然后在域外定义
声明的规则跟普通函数声明规则一样,但在域外定义时要在函数名前加上“ 域名 + ::”,这样编译器才知道这个函数是属于哪个域的。
class Date
{
public:
void PrintDate(int year, int month, int day);
private:
//...
};
void Date::PrintDate(int year, int month, int day) //切记一定要说明是属于哪个域的
{
cout << year << month << day << endl;
}
3、类的实例化
因为类只是一个自定义类型的声明,只是说明这个类型下有哪些变量,哪些函数而已,本身是不占空间的。但如果以这个类型定义了一个变量,即实例化,那么就会占用一定空间了。
打个比方,如果把类看作是一张菜谱,那么以这个类型定义的变量就是一道道菜。但菜谱是不占空间的,而菜则占空间。
class Date /*自定义类型声明,不消耗空间*/
{
int _year;
int _month;
int _day;
};
int main()
{
Date d; /*实例化,消耗空间*/
return 0;
}
4、如何计算类的大小
类的大小计算方法和结构体的如出一辙,都要考虑对齐问题。但要注意的是,无论类还是结构体,最后的大小都要是最大对齐数的整数倍。
5、this 指针
(1)什么是 this 指针
这里先举一个栈的例子。在 C 语言中模拟压栈、初始化栈、取栈顶元素等操作是不是都是这样的:
Stack st;
/* 初始化栈 */
STInit(&st);
/* 压栈 */
STPush(&st, x);
/* 取栈顶元素 */
int top = STTop(&st);
但是,C++ 是这样操作的:
class Stack
{
public:
void STInit()
{
//...
}
void STPush(int x)
{
//...
}
int STTop()
{
//...
}
private:
int capacity;
int size;
int *a;
};
int main()
{
Stack st;
/*栈初始化*/
st.STInit();
/*压栈*/
st.STPush(1);
/*取栈顶元素*/
int top = st.STTop();
return 0;
}
不难看出,其实 C++ 中 this 指针干的事其实就是相当于 C 的 &st。
因此不难看出,其实 this 是 C++ 成员函数中自带的形参,且一般情况下由 ecx 寄存器实现,只不过是隐形的形参罢了。其功能也就是负责把变量的地址传到函数里。
(2)this 指针的特性
类型:*const,即无法改变其地址。
注意事项:语法上是可以传 NULL 给 this 指针的,但如果当成员函数里要通过 this 访问成员变量时,就会由于空指针解引用而报错,而且还是运行报错。
void print()
{
cout << _year << endl; /*空指针解引用 -> 报错*/
}
void print()
{
cout << 'a' << endl; /*没对 this 指针解引用,程序正常运行*/
}