类和对象

一、类和对象

  1.1对象和类的概念

对象占空间,类不占空间

 类:相对于构造数据类型

1.2 类的确定和划分

 基本原则:寻求系统中各事物的共性,将具有共性的那些东西划分成一个类;设计类应有明确的标准,设计的类应该是容易理解和使用的。同一系统,达到的目标不同,确定和划分的类也不同。

二、类的声明

1.类声明的形式

 class   类名

{

     private:私有成员数据和成员函数

    protect;保护成员数据和成员函数

   public:公有成员数据和成员函数

}:

class与struct的区别:class的默认权限是私有 private

                                   struct的默认权限是公共  public

2.类声明的内容及成员的访问控制

 (1)类声明的内容

        成员数据:声明成员数据的数据类型、名字,以及访问权限

        成员函数:定义成员函数及对它们的访问权限 。 类内类外都可以定义成员函数。

(2)访问权限

        private:私有函数只能被本类的成员函数访问

        protect:一般情况下与私有成员的含义相同,它们的区别在于1类的继承中对新类的影响不同。

       public:公有成员可以被程序中任何函数访问。

#include<iostream>
using namespace std;
#include<string>
class Student
{
public:
	string m_Name;
	int m_ID;
	void showStudent()
	{
		cout << "姓名:" << m_Name << " 学号: " << m_ID << endl;
	}

	void setName(string name)//李四
	{
		m_Name = name;
	}
	void setID(int ID)
	{
		m_ID = ID;
	}

};
int main()
{
	Student s1;
	s1.m_Name = "张三";
	s1.m_ID = 1;
	s1.showStudent();

	Student s2;
	s2.setName("李四");
	s2.m_ID = 2;
	s2.showStudent();

	Student s3;
	s3.setName("王五");
	s3.setID(3);
	s3.showStudent();




	return 0;
}

三、构造函数和析构函数

3.1构造函数

 1.构造函数的作用

    对对象进行初始化分配内存空间

2.构造函数的定义与使用

  (1)构造函数的名字必须与类的名字相同

  (2)构造函数的参数可以是任何数据类型,但它没有返回值

  (3)对象定义时,编译系统会自动地调用构造函数完成对象内存空间的分配和初始化工作

  (4)构造函数是类的成员函数,具有一般成员函数的所有性质,可访问类的所有成员,可以是内联函数,可以带有参数表,可以带有默认的形参,可以重载

       int  main()

{

     circle  p1,p2;

}

看到p1,p2  ① 构造函数的调用 ② 确定是否有参 ③ 寻找类中的circle构造函数 ④ 1.重载(无参)

              circle()

           {x=0,y=0,r=0;}

             2  默认参(无参)

           circle(x=0,y=0,r=0)

          {x=x1,y=y1,r=r1;}

              3 类中无circle构造函数,系统自动调用circle函数,且值随机

              4 类中有circle构造函数,但是有参,则系统报错

#include<iostream>
using namespace std;
// 构造函数两种分类方式
//1 按参数分:有参构造和无参构造(默认构造)
//2 按类型分:普通构造和拷贝构造
class Person
{
public:
	Person()
	{
		cout << "Person的构造函数调用" << endl;
	}
	Person(int a)
	{
		age = a;
		cout << "Person的有参构造函数调用" << endl;
	}
	//拷贝构造函数
	Person(const Person &P)
	{
		//将传入的人身上的所有属性,拷贝到我身上
		age = P.age;
		cout << "Person的拷贝构造函数调用" << endl;
	}
	~Person()
	{
		cout << "Person的析构函数调用" << endl;
	}
	int age;
};
//三种调用方法
void test01()
{
//1.括号法
	Person P;//调默认构造	
	Person P2(10);//调用有参构造函数
	Person P3(P2);//拷贝函数
	//注意1  调用默认构造是,不加()   
	//cout << "p2的年龄为: " << P2.age << endl;
	//cout << "P3的年龄为: " << P3.age << endl;

   //2.显示法
   Person P4;
   Person P5 = Person(10);//有参构造
   Person P6 = Person(P5);//拷贝构造
   Person(10);//单独拿出来,为匿名对象  特点:当前行执行结束后,系统会立即回收掉匿名对象
   // 注意2  不要利用拷贝构造函数初始化匿名对象,如Person(P4)==Person P4

   //3.隐式转换法
   Person P7 = 10;//相对于Person P7=Person(10)  有参构造
   Person P8 = P7;//拷贝构造
}


int main()
{  
	test01();

}

  3.2 拷贝构造函数

    拷贝构造函数是一种特殊的构造函数,具有一般构造函数的所有特征,其形参是本类对象的引用。其作用是使用一个已经存在的对象去初始化一个新的同类对象。

   一般形式为:

                      class   类名

                      {

                            public:

                                 类名(形参表)

                                 类名(类名& 对象名);

                     };

                     类名::类名(类名&对象名);

                     {

                              函数体

                     }

3.3 析构函数 <特殊的成员函数>

     析构函数与构造函数的作用相反,它用来完成对象被删除前的扫尾工作。

     特征:

         ① 析构函数是在类名前加求反符号“ ~”构成

         ② 析构函数不指定返回值

         ③析构函数没有参数,也不能重载(与默认参不可共存)析构函数,即一个类只能定义一个析构函数。

         ④在撤销对象前,系统自动调用析构函数

 系统会自动调用析构函数撤销对象的三种情况:

          1.对象的作用域结束

          2.用delete运算符释放new运算符创建的对象

          3.生成的临时对象使用完毕后

#include <iostream>
using namespace std;
//对象的初始化和清理

//1.构造函数 进行初始化操作
class Person
{
public:	
	//1.1 构造函数  没有返回值,不要写void  函数名与类名相同  可以有参数,也可以重载 会自已调用,且只一次
	Person()
	{
		cout << "构造函数的调用" << endl;
	}
	
};

//2.析构函数 进行清理操作
//析构函数  没有返回值,不写void 函数名与类名相同,名称前加~  不可以有参数,不可以重载  对象销毁前自动调用且只一次
~Person()
{
	cout << "Person的析构函数调用" << endl;
 }


//构造和析构都是必须有的实现,如果自已不提供,编译器会提供一个空实现的构造和析构
void test01()
{
	Person p;//在栈上的数据,test01执行完毕后,释放这个对象
}
int main()
{
	//test01(); 构造和析构都有,与上文void函数连在一起
	Person P;//只有实现构造,没有析构(main函数还没有完成,P不释放)



	system("pause");
	return 0;

}

   四、对象应用 

   4.1 对象成员

    一般格式:<类名>(<形参表>):<成员对象1>(<实参表1>),<成员对象2>(<实参表2>),```````

{

      ········                 //类成员的初始化

}

注意:

     (1)成员对象的初始化必须在该类的构造函数的成员初始化列表中进行

     (2)执行构造函数时,先执行所有成员对象的构造函数,再执行本类对象的构造函数。构造函数的顺序仅与成员对象在类中说明的顺序有关。

     (3)析构函数与构造函数的执行顺序相反。

#include <iostream.h>
class Counter {
    int val;
  public:
    Counter()  {val=0;cout<<"Default Constructor  of Counter"<<endl;}       
    Counter(int x)  {val=x;cout<<"Constructor of Counter"<<val<<endl;}     
   ~Counter()  {}     {cout<<"Destructor of Counter"<<val<<endl;} 
};
class Example{
    Counter c1,c2;
   public:
       Example()     {val=0;cout<<"Default Constructor  of Example"<<endl;} 
       Example(int x):c2(x),c1()
        {val=x;cout<<" Constructor  of Example"<<val<<endl;}      
      ~Example()     {cout<<"Destructor of Example"<<val<<endl;}  
     void  Print()    {cout<<"value= "<<val<<endl;}    
         };
void main()
{
    Example e1,e2(4);
    e2.Print();
}

结果:

Default Constructor  of Counter
Default Constructor  of Counter
Default Constructor  of Example
Default Constructor  of Counter
Constructor of Counter :4
Constructor  of Example 4
value= 4
Destructor of Example :4
Destructor of Counter :4
Destructor of Counter :0
Destructor of Example :0
Destructor of Counter :0
Destructor of Counter :0



4.2 对象数组

对象数组的定义格式:<类名>  <数组名>[<大小>]·····;

使用对象数组成员的一般格式:<数组名> [<下标表达式>].<成员名>

五、友元函数和友元类

5.1友元函数

 一般形式:friend <数据类型><友元函数名>(参数表);

     class B

{   ········

   friend  class A;

   ··········

A类所有成员函数可以访问B的私有数据

5.2 友元类

    友元类声明:

       friend class<友元类名>;   或 friend <友元类名>

 注意   ① 友元关系是不能传递的。

           ② 友元关系是单向的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值