FP-03 对象与类

Lecture 03 对象与类

对象构成了面向对象程序的基本计算单位,而对象的特征则由相应的类来描述。

对象是用类来创建的,因此,程序中首先要定义类。

C++的类是一种用户自定义类型,定义形式如下:

class <类名> { <成员描述> } ;
  • 成员包括:数据成员成员函数
  • 类成员标识符的作用域为整个类定义范围。

数据成员

数据成员是对类的对象所包含的数据描述,它们可以是常量和变量,类型可以是任意的C++类型(void除外) 。

数据成员的描述格式与C的结构成员的描述格式相同,例如:

class Date {//类定义
 ......
 private: //访问控制说明
 int year,month,day; //数据成员描述
};

在C++旧标准中,描述数据成员时不允许进行初始化(某些静态数据成员除外)。例如:

class A { 
  int x=0;   //Error
  const double y=0.0;   //Error
  ......
};

成员函数

成员函数是对类定义中的数据成员所能实施的操作描述。

成员函数的实现(函数体)可以放在类定义中,例如:

class A
{ ...
  void f() {...} //建议编译器按内联函数处理
};

成员函数的实现也可以放在类定义外,例如:

class A
{ ...
  void f(); //声明
};

void A::f() { ... } //要用类名受限,区别于非成员函数(全局函数)

注意:在C++中,也允许在结构(struct)和联合(union)中定义函数,但成员的访问控制与类不同!

类成员函数名是可以重载的(析构函数除外),它遵循一般函数名的重载规则。例如:

class A { 
 ......
 public:
 void f();
 int f(int i);
 double f(double d);
  ......
};

类成员的访问控制

在C++的类定义中,可以用访问控制修饰符public、private或protected来控制在类的外部对类成员的访问限制。例如:

class A
{	public: //访问不受限制。 
		int x;
		void f();
	private: //只能在本类和友元的代码中访问。 
		int y;
		void g();
	protected: //只能在本类、派生类和友元的代码中访问。 
		int z;
		void h();
};

在C++的类定义中,可以有多个public、private和protected访问控制说明;默认访问控制是private。例如:

class A
{		int m,n; //m,n的访问控制为private。
	public:
		int x;
		void f()private:
		int y;
		void g();
	protected:
		int z;
		void h();
	public:
		void f1();
};

一般来说,类的数据成员和在类的内部使用的成员函数应该指定为private,只有提供给外界使用的成员函数才指定为public。

  • 具有public访问控制的成员构成了类与外界的一种接口(interface)。
  • 在一个类的外部只能访问该类接口中的成员。

protected类成员访问控制具有特殊的作用(在派生类中使用)。

对象

类属于类型范畴的程序实体,它一般存在于静态的程序(编译程序看到的)中。

而动态(运行中)的面向对象程序则是由对象构成。

对象在程序运行时创建。

对象的创建和标识

直接方式

通过在程序中定义一个类型为类的变量来实现的。例如:

class A {
public:
   void f();
   void g();
private:
   int x,y;
}
......
    
A a1; //创建一个A类的对象。

A a2[100]; //创建100个A类对象。

对象在进入相应变量的生存期时创建,通过变量名来标识和访问。相应变量的生存期结束时,对象消亡。

分为:全局对象、局部对象和成员对象。

间接方式(动态对象)

在程序运行时刻,通过用new操作来创建对象,用delete操作来撤消(使之消亡)。对象通过指针来标识和访问。

单个动态对象的创建与撤消

A *p;
p = new A; // 创建一个A类的动态对象。*p … //或,p->...,通过p访问动态对象
delete p;  // 撤消p所指向的动态对象。

动态对象数组的创建与撤消

A *q;
q = new A[100];  //创建一个动态对象数组。
...q[i]... //或,*(q+i),访问动态对象数组中的第i个对象
delete []q;  //撤消q所指向的动态对象数组。 

成员对象

对于类的数据成员,其类型可以是另一个类。即,一个对象可以包含另一个对象(称为成员对象)。例如:

class A
{ ...
};

class B
{ ...
  A a; //成员对象
  ...
};

B b; //对象b包含一个成员对象:b.a

成员对象跟随包含它的对象一起创建。

在类中说明一个数据成员的类型时,如果未见到相应类型的定义,或相应的类型未定义完,则该数据成员的类型只能是这些类型的指针或引用类型。例如:

class A; //A是在程序其它地方定义的类,这里是声明。

class B
{ A a; //Error,未见A的定义。
  B b; //Error,B还未定义完。
  A *p; //OK
  B *q; //OK
  A &aa; //OK
  B &bb; //OK
}; 

对象的操作

对于创建的一个对象,需要通过向它发送消息(调用对象类中定义的某个public成员函数)来对它进行操作。例如:

class A
{		int x;
	public:
		void f();
};
int main()
{	A a; 	//创建A类的一个局部对象a。
	a.f(); 	//调用A类的成员函数f对对象a进行操作。
	A *p=new A;	 //创建A类的一个动态对象,p指向之。
	p->f(); 	//调用A类的成员函数f对p所指向的对象进行操作。
	delete p;
	return 0;
}

在类的外部,通过对象来访问类的成员时要受到类成员访问控制的限制,例如:

class A
{	public:
		void f() 
		{ ...... //允许访问:x,y,f,g,h 
		}
	private:
		int x;
		void g() 
		{ ...... //允许访问:x,y,f,g,h 
		}
	protected:
		int y;
		void h();
};
void A::f() //或A::g、A::h
{ ...... //允许访问:x,y,f,g,h
   A a;
   ...//能访问a.x、a.y、a.g和a.h
}
void func()
{  A a;
a.f();  //OK
a.x = 1;  //Error
a.g();  //Error
a.y = 1;  //Error
a.h();  //Error
......
}

可以对同类对象进行赋值

Date yesterday,today,some_day;
some_day = yesterday; //默认是把对象yesterday的
  //数据成员分别赋值给对象some_day的相应数据成员

取对象地址

Date today;
Date *p_date;
p_date = &today; //把对象today的地址赋值给指针p_date

把对象作为参数传给函数。例如:

void f(Date d) //创建一个新对象d,其数据成员用实参对象的数据成员对其初始化
{ ...... }

void g(Date &d) //不创建新对象,d就是实参对象!
{ ...... }

Date today;
f(today); //调用函数f,对象today不会被f修改
g(today); //调用函数g,对象today会被g修改!

把对象作为函数的返回值。例如,

Date f(Date &d)
{ d.print(); //输出:2020.2.20
   return d;  //创建一个临时对象作为返回值,用d对其初始化
}
Date& g(Date &d)
{ d.print(); //输出:2020.2.20
   return d;  //不创建新对象,把对象d作为返回值
}
Date some_day; //创建一个日期对象
some_day.set(2020,2,20); 
f(some_day).set(2017,3,13); some_day.print() //?
g(some_day).set(2017,3,13); some_day.print() //?
//前者显式:2020.2.20,因为修改的是临时对象
//后者显式:2017.3.13,因为修改的是some_day!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值