今天我们来看看c++最重要的一个知识点:类与对象。类与对象绝对是c++面向对象的核心。类与对象主要分为三部分:封装,继承和多态。下面一个一个来看吧。
首先public修饰的成员在类外可以直接被访问。protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)
1.封装:我们使用类将数据和方法都封装起来。不想对外开放的就用 protected/private 封装起来,用 public 封装的成员允许外界对其进行合理的访问。所以封装本质上是一种管理。
类的作用域: Person::PrintPersonInfo()// 在类外需要指定PrintPersonInfo(类内函数)是属于Person这个类域 void。
在类外定义一个这个类的变量,这个变量可以调用这个类的属性
例子:class Person
{
public:
void PrintPersonInfo();
private:
char _name[20];
char _gender[3];
int _age;
};
void test()
{
Person man; //类的实例化
man._name="hehe";
man._age="66";
man._sex="男";
man._PrintPersonInfo();
}
this指针:
特性:
this指针的类型:类类型* const,只能在“成员函数”的内部使用,this指针本质上其实是一个成员函数的形参,是对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针。this指针是成员函数第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递。(小白看了估计都懵了,博主也是这样的啦)
构造函数:分有参构造函数和无参构造函数
- 函数名与类名相同。
- 无返回值。
- 对象实例化时编译器自动调用对应的构造函数。
- 构造函数可以重载。
- 如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,
析构函数:1.析构函数名是在类名前加上字符 ~。
2.无参数无返回值。
3.一个类有且只有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。
编译器自动生成的析构函数机制:
1、编译器自动生成的析构函数对内置类型不做处理。
2、对于自定义类型,编译器会再去调用它们自己的默认析构函数。
4.对象生命周期结束时,C++编译系统系统自动调用析构函数。
5.先构造的后析构,后构造的先析构
拷贝构造函数:主要是浅拷贝和深拷贝(前面讲过,这里就不说了)
- 拷贝构造函数是构造函数的一个重载形式。
- 拷贝构造函数的参数只有一个且必须使用引用传参,使用传值方式会引发无穷递归调用。
- 实际例子区分构造函数和拷贝构造函数。
- Date(int year = 0, int month = 1, int day = 1)// 构造函数
{
_year = year;
_month = month;
_day = day;
}
Date(const Date& d)// 拷贝构造函数 ,与构造函数形成函数重载。注意要加上const
{
_year = d._year;
_month = d._month;
_day = d._day;
}
运算符重载的知识点前面的文章也都有讲过啦,这里也不多说。
const修饰成员函数:const修饰类成员函数,实际修饰的是类成员函数隐含的this指针,表明在该成员函数中不能对this指针指向的对象进行修改。
void Print()const// 对类成员函数中的打印函数进行const修饰,避免在函数体内不小心修改了对象。
{ cout << _year << "年" << _month << "月" << _day << "日" << endl; }
explicit关键字:隐式类型转换。若是想禁止单参数构造函数的隐式转换,可以用关键字explicit来修饰构造函数。
static成员:
声明为static的类成员称为类的静态成员。用static修饰的成员变量,称之为静态成员变量;用static修饰的成员函数,称之为静态成员函数。静态成员变量一定要在类外进行初始化。
静态成员_n是存储在静态区的,属于整个类,也属于类的所有对象。所以计算类的大小或是类对象的大小时,静态成员并不计入其总大小之和。所以sizeof(静态类名)=1。
静态成员变量必须在类外定义,定义时不添加static关键字
例子:class Test
{ private: static int _n; }; // 静态成员变量的定义初始化
int Test::_n = 0;//类外定义
静态成员函数没有隐藏的this指针,不能访问任何非静态成员
实例:
class Test
{
public:
static void Fun()
{
cout << _a << endl; //报错,不能访问非静态成员
cout << _n << endl; //正确,
}
private:
int _a; //非静态成员
static int _n; //静态成员
};
访问静态成员变量的方法:
1.当静态成员变量为公有时,有一下几种访问方式:
实例:
class Test
{
public:
static void Fun()
{
cout << _a << endl; //error不能访问非静态成员
cout << _n << endl; //correct
}
private:
int _a; //非静态成员
static int _n; //静态成员
};
2.当静态成员变量为私有时,有以下几种访问方式:
#include <iostream>
using namespace std;
class Test
{
public:
static int GetN()
{
return _n; //既然你的成员是私有的,那么我就通过公有的函数来返回你私有的成员
}
private:
static int _n;
};
// 静态成员变量的定义初始化
int Test::_n = 0;
int main()
{
Test test;
cout << test.GetN() << endl; //1.通过对象调用成员函数进行访问
cout << Test().GetN() << endl; //2.通过匿名对象调用成员函数进行访问
cout << Test::GetN() << endl; //3.通过类名调用静态成员函数进行访问
return 0;
}
友元函数:
友元函数说明:
1、友元函数可以访问类是私有和保护成员,但不是类的成员函数。
2、友元函数不能用const修饰。
3、友元函数可以在类定义的任何地方声明,不受访问限定符的限制。
4、一个函数可以是多个类的友元函数。
5、友元函数的调用与普通函数的调用原理相同。
实例:
(博主的千年老图,hhh)
友元类:友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中非公有成员。友元类说明:
1、友元关系是单向的,不具有交换性。
例如上述代码中,B是A的友元,所以在B类中可以直接访问A类的私有成员变量,但是在A类中不能访问B类中的私有成员变量。
2、友元关系不能传递。
如果A是B的友元,B是C的友元,不能推出A是C的友元。
实例:
内部类:
如果一个类定义在另一个类的内部,这个内部类就叫做内部类。注意此时这个内部类是一个独立的
类,它不属于外部类,更不能通过外部类的对象去调用内部类。外部类对内部类没有任何优越的访问权限。
注意:内部类就是外部类的友元类。注意友元类的定义,内部类可以通过外部类的对象参数来访问外部类中的所有成员。但是外部类不是内部类的友元。
特性:
1.内部类可以定义在外部类的public、protected、private都是可以的。
2.注意内部类可以直接访问外部类中的static、枚举成员,不需要外部类的对象/类名。
3.sizeof(外部类)=外部类,和内部类没有任何关系。
好啦,今天就分享到这啦,类的有关知识还有很多很多。下次再分享啦
本贴为博主亲手整理。如有错误,请评论区指出,一起进步。谢谢大家的浏览.