类的定义:
类中的成员分三种,分别是:1、public 公共的 2、private私有的 3、protected 受保护的。
类即为对对象的抽象,具体对象所具有的属性,当我们定义了类,然后又如何定义一个实际的对象呢?如上图,我们有了Dog这个类,接下来如何定义dog1、dog2这些具体的对象呢?在实例化对象时,我们有两种方式:1、从堆中实例化 2、从栈中实例化。
从栈中实例化对象:
从堆中实例化对象:
以上,我们可以看到,在栈中实例化对象不需要我们手动申请和释放内存。而在堆中实例化对象,则是以指针的形式来进行,这需要我们手动申请内存空间并且在是用完以后将其手动释放。
对象成员的访问:
string类型 及其常用操作
类内定义:
即将类内函数的实现函数体也定义在类的内部
类外定义:即将函数体的实现写在类定义以外,可以是同文件也可以是分文件
构造函数
构造函数在对象实例化时自动调用,构造函数与类同名并且没有返回值。构造函数可以有多个重载形式,实例化对象时仅用到一个构造函数,当用户没有定义构造函数时,编译器会自动生成一个构造函数。
内存分区:
构造函数初始化列表以及其在多层继承中的使用:
在函数后接红框以内代码,其中其类定义如下
上面函数为其函数体的实现,初始化时,将对应参数传到类对象内相对应的变量成员。
而在有继承关系时,如下
m_strName为Person中数据成员,Soldier将其继承。在Soldier(string name, int age)构造函数初始化时,在传递name值时,我们还是会将其传到Person中,如下:
再由Person的构造函数完成初始化,如下:
多层继承时也是如此,构造函数一层一层的调用。
class Time
{
// 友元类
friend Watch;
public:
Time(int hour, int min, int sec)
{
m_iHour = hour;
m_iMinute = min;
m_iSecond = sec;
}
public:
int m_iHour;
int m_iMinute;
int m_iSecond;
};
/**
* 定义Watch类
* 数据成员:m_tTime
* 成员函数:构造函数
* display用于显示时间
*/
class Watch
{
public:
Watch(Time &t):m_tTime(t)
{
}
void display()
{
cout << m_tTime.m_iHour << endl;
cout << m_tTime.m_iMinute << endl;
cout << m_tTime.m_iSecond << endl;
}
public:
Time m_tTime;
};
在这种类当中,构造行数传参以数据成员的类型为准。
拷贝构造函数
拷贝构造函数是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象。拷贝构造函数通常用于:
-
通过使用另一个同类型的对象来初始化新创建的对象。
-
复制对象把它作为参数传递给函数。
-
复制对象,并从函数返回这个对象。
如果在类中没有定义拷贝构造函数,编译器会自行定义一个。如果类带有指针变量,并有动态内存分配,则它必须有一个拷贝构造函数。
析构函数在函数销毁时自动调用,会用来做一些如内存销毁,归还系统资源等任务。
浅拷贝:即 将原有已申请空间的地址赋值给一个新值,新值与原有值共用一块地址空间,所以值也相同。
深拷贝:重新申请一块内存空间,将已申请空间中的旧值赋值给新空间的地址上,它们虽然值相同,但地址空间已经不同。