【类和对象】



 

 



 
 
 

 

 

 

【类的定义】

结构体只描述了一个物体的属性,而类不仅描述了一个物体的属性,而且还描述了一个物体的行为。在类中,如果没有指名成员的类型,则默认为私有成员;在结构体中,如果没有指名成员的类型,则默认为公有成员。

一个类里面包括:成员变量和成员函数。

成员变量:该类事物所具有的属性。

成员函数:该类事物所具有的行为。

类的完整声明

class C

{

public:

         公用的数据和成员函数 ...;

private:

         私有的数据...;

protected:

         保护的数据和成员函数...;

};  //分号不能丢

 

示例一

class CUser

{

public

         char m_Username[128];  //成员变量

         char m_Password[128];

         bool Login();          //成员函数

};

 

bool CUser::Login()          

{

  //相关操作

}

 

示例二

class CUser                       //声明一个类

{

public:

         char m_Username[128]; //定义数据成员

         char m_Password[128];  //定义数据成员

 

         bool Login()                   //定义方法

         {

                   //相关操作

         }

};

二种方法一样,但是一比较常用,因为方式一把定义和使用分开,是程序的可读性提高。

【类的对象】

对象就是类的实例化。

类是一种数据类型,对象就是这个类数据类型的变量。(可以这么去理解)

 

class Pen                        //声明一个类 Pen

{

public:                                //表示下面声明的变量都是公有的

         int size;                 //声明一个公有的成员变量size

         void write();            //声明一个公有的成员函数write

};

Pen  pen ;  //这里是声明一个Pen类的对象

理解: CPen 就相当于一个笔的模型,这就是这个类不是其他的东西(比如车、房子、桌子...),而已经是个笔了。pen前提下它是一支笔,至于是 钢笔、油笔、铅笔、还是别的笔,就是对象。

类是不占内存空间的,只有实例化对象后才占内存。

类成员的访问】

当定义一个类的对象之后,就可以对这个类的成员进行访问调用了。

class Pen                    //声明一个类 Pen

{

public:                                //表示下面声明的变量都是公有的

         int size;             //声明一个公有的成员变量size

         void write();            //声明一个公有的成员函数write

};

 

int main()

{

         Pen pen ;               //定义一个对象pen

         pen.size=10;             //为对象pensize赋值

 

         cout <<"the size is " <<pen.size <<endl;

         return 0;

}

如果定义的是类的指针,则用" -> "来访问成员。

Pen * p = new Pen;

p->size = 20;

p->write();  //调用成员函数

使用类的对象时,为什么要初始化? 

因为在使用类的对象的时候,必须进行初始化,否则对象里面是垃圾值。

【构造函数】

构造函数是特殊的成员函数,它的函数名必须与类的名称一致,并且不是由用户来调用的,而是在建立对象的同时自动执行的。并且构造函数没有返回值,可以有参数,可以重载。

 

为什么要构造函数?

因为在类中,私有成员和保护成员不能通过类的示例对象进行初始化。而使用构造函数来进行对象的成员初始化。

class A

{

private

         int m_size = 10;   //error,不能在类中进行初始化

public

         int m_size = 10;   //这样是可以的,但这样数据就可以被外界更改,失去了数据封装性。

}

示例:

class Pen

{

public:

         Pen(int size=10);      //声明具有默认参数的默认构造函数

         int GetSize();             //成员函数的声明

         int SetSize(int size);

         void Write();

private:

         int m_size;

};

Pen::Pen(int size)

{

         m_size=size;

}

void Pen::Write()

{

         cout<<"the size of pen is "<<m_size<<endl;

}

int main()

{

         Pen pen1;                   //默认参数的构造函数的调用

         pen1.Write();

         Pen pen2(15);           //参数取代默认参数的构造函数调用

         pen2.Write();

         return 0;

}

/*

the size of pen is 10

the size of pen is 15

Press any key to continu

*/

【拷贝构造函数】

当需要很多相同的对象时,就要进行多次重复的初始化,所以需要拷贝构造函数来实现。

拷贝构造函数:

深拷贝(通常用于当构造函数分配有堆内存资源(动态分配)时),

浅拷贝(一般的拷贝)。

示例:

#include "stdafx.h"

#include<iostream>

using namespace std;

class Pen                    //声明一个Pen

{

private:

         int m_size;

public:

         Pen(int size);

         Pen(Pen &pen);                 //声明一个Pen类的复制构造函数(拷贝构造函数)

         int GetSize();

         void Write();

};

Pen::Pen(int size)

{

         m_size=size;

}

Pen::Pen(Pen &pen)                  //复制构造函数的定义(拷贝构造函数的定义方式)

{

         m_size=pen.GetSize();

         cout<<"size and long";

}

int Pen::GetSize()

{

         return m_size;

}

void Pen::Write()

{

         cout<<"the value of m_size is "<<GetSize()<<endl;

}

int main()

{

         Pen pen1(10);

         pen1.Write();

         Pen pen2(pen1);                //调用复制构造函数

         pen2.Write();

         return 0;

}

经验:如果你的类需要析构函数来析构资源,则它也需要一个拷贝构造函数。

因为对象都是自动析构的,如果需要一个自定义的析构函数,那就意味着也需要一个拷贝构造函数。

如果不自定义构造函数、析构函数、拷贝构造函数,则系统会调用默认的相应的函数。

【析构函数】

因为当使用完对象时,要进行清理,所以需要析构函数。

 

什么是析构函数?

特殊的类成员函数,它没有返回类型,没有参数,不能随意调用,也没有重载。只有在类对象生命期结束的时候,由系统自动调用。

一个类可以有多个构造函数,但是只能有一个析构函数。

 

析构函数的定义方法:

在构造函数名前加上“~”,表示“逆构造函数”。

如: 构造函数  pen()

     析构函数 ~pen()

示例:

#include "stdafx.h"

#include<iostream>

using namespace std;

class Pen

{

public:

         Pen(int size=10);                                                    

         ~Pen();                        //声明析构函数

         int GetSize();

         int SetSize(int size);

         void Write();

private:

         int m_size;

};

Pen::Pen(int size)

{

         m_size=size;

}

Pen::~Pen()                         //定义析构函数

{

         cout<<"this is destructor called"<<m_size<<endl;

}

void Pen::Write()

{

         cout<<"the size of pen is "<<m_size<<endl;

}

int main()

{

         Pen pen1;

         pen1.Write();

         Pen pen2(15);

         pen2.Write();

         return 0;

}

/*

the size of pen is 10

the size of pen is 15

this is destructor called15

this is destructor called10

Press any key to continue

*/

【类的继承】

继承是一种编程技术,也是面向对象程序设计的一个非常重要的特征。是C++语言的精华和真谛。类继承的新类称为派生类或子类,原有类称为基类或父类。继承父类的子类,可以调用父类的成员数据或成员函数。

 

继承的分类:

单一继承:以一个基类派生新类。

多重继承:继承多个基类。

 

派生新类的语法

单一继承

语法: class 派生类名 : 访问限定符 基类名

例如: class A : public B

多重继承:

语法: class 类名称 : 访问限定符基类1名称, 访问限定符基类2名称...

例如: class C: public class A, public class B

 

【覆盖成员函数】

如果在派生类中声明一个成员函数,这个成员函数与基类的一个成员函数相同,当定义派生类的对象时,通过对象调用这个成员函数时,那么访问的是派生类中的还是基类中的呢?访问的是派生类中的成员函数。这就叫做成员函数的覆盖。

注意:如果此时想要派生类去调用基类的成员函数,这要加上作用域限定符“::”。如:rect.CShare::display()

 

示例:

#include "stdafx.h"

#include<iostream>

using namespace std;

 

class CShape                                //声明一个CShape

{

private:

         int m_color;                        //声明一个私有成员变量

public:

         CShape(int color=10);                //声明带有默认参数的构造函数

         void display();                             

};

CShape::CShape(int color)                 //默认参数的构造函数的定义

{

         m_color=color;                            //对成员变量进行赋值

}

void CShape::display()                        //CShape成员函数的定义

{

         cout<<"This is a Shape"<<endl;

}

class CRect :public CShape               //声明一个派生自CShape类的CRect

{

private:

         int m_size;                          //声明一个私有成员变量

public:

         CRect(int size=20);           //声明默认参数的构造函数

         void display(); 

};

CRect::CRect(int size)                        //默认参数的构造函数的定义

{

         m_size=size;

}

void CRect::display()                           //CRect的成员函数的定义

{

         cout<<"This is a Rect"<<endl;

}

int main()

{

         CShape shape;

         shape.display();                 //调用CShape类的成员函数

         CRect rect;                         //定义CRect类的对象

         rect.display();                     //调用派生类CRect的成员函数

         rect.CShape::display();             //通过限定符来用派生类调用基类的成员函数

         return 0;

}

/*

This is a Shape

This is a Rect

This is a Shape

Press any key to continue

*/

 

【类模板】

类模板能够为类的数据成员、成员函数的参数、返回值提供动态参数化的机制,使得用户可以方便地设计出功能更为灵活的类。

 

定义格式:

template< 参数类型列表 >

返回值 类名<参数类型列表>::函数名(参数列表)

{ 函数体内容; }

 

示例:

类模板中的每个成员函数定义都要在前面加上template<class T>

template<class T>

T Calculate<T>::Add()

{

         return m_a + m_b;

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值