C++学习(4-1)

这次要讨论的是类的相关知识。类是C++最重要的特性。一个类的定义包含了两部分:类声明与类函数定义。

///类的实现
#include<iostream>
using namespace std;
class item//类声明,关键词class
{
	int number;//类变量声明,默认为私有
	float cost;//私有成员不可被类外访问
public:
	void getdata(int a,float b);//函数声明
	void putdata(void)//类内的函数定义,需要注意,当函数定义于类内时,它变成一个内联函数,因此只有小函数才在类内定义
	{
		cout<<number<<endl;
		cout<<cost<<endl;//改函数的作用是,显示私有变量的值
	}
};//类的声明以分号结尾
void item::getdata(int a,float b)//类外的函数定义,格式:返回类型 类名::函数名(参数声明){ 函数体 }
{
	number=a;
	cost=b;//该函数的作用是,为类中的数据变量赋值
}
int main()
{
	item x;//创建类对象x
	cout<<"\nobject x"<<endl;
	x.getdata(100,299.95);//利用类对象,使用点操作符(.)对成员函数进行调用
	x.putdata();//类的成员函数只能通过该类的对象调用,并且要使用点操作符

	item y;//创建类对象y
	cout<<"\nobject y"<<endl;
	y.getdata(200,175.50);
	y.putdata();

	return 0;
}

该程序点明了类的基本运用及注意点,要定义类的时候参照以上程序就能基本实现了。

/程序2.成员函数的嵌套:成员函数被同类的另一个成员函数调用
//一般情况下,类内所有数据项声明为私有,所有函数声明为公共
//但对于声明为类的私有成员函数而言,只能被类的另一个成员函数调用
#include<iostream>
using namespace std;
class set//类set的声明,改类包含两个整型私有变量即三个成员函数
{
	int m,n;
public:
	void input(void);//为类的两个私有数据赋值
	void display(void);//显示数据
	int largest(void);//获取较大的一个数
};
int set::largest(void)//类set成员函数largest的定义
{
	if(m>=n)
		return(m);
	else
		return(n);
}
void set::input(void)//类set成员函数input的定义
{
	cout<<"Input values of m and n:"<<endl;
	cin>>m>>n;
}
void set::display(void)//类set成员函数set的定义
{
	cout<<"Largest values="<<largest()<<endl;//调用成员函数
}
int main()
{
	set A;//创建类set的一个对象A
	A.input();
	A.display();

	return 0;
}

在上述程序中,类的成员函数display()中嵌套调用类的成员函数largest(),这说明了成员函数可被同类的另一个成员函数调用。

///程序3.类内数组的使用--处理商品列表
//本程序执行如下任务:添加商品、删除某个商品、显示所有商品价格总和、显示所有商品的详细信息
#include<iostream>
using namespace std;
const int m=50;//设置常数m,表示最多能输入的商品数
class ITEMS//商品类ITEMS声明
{
	int itemCode[m];//商品的条形码的类内数组
	float itemPrice[m];//商品的价格的类内数组
	int count;//当前记录的商品数
public:
	void CNT(void){count=0;}//初始化商品数
	void getitem(void);
	void displaySum(void);
	void remove(void);
	void displayItems(void);
};
void ITEMS::getitem(void)//添加商品(表示进货)
{
	cout<<"Enter item code:";
	cin>>itemCode[count];
	cout<<"Enter item cost:";
	cin>>itemPrice[count];
	count++;
}
void ITEMS::displaySum(void)//显示所有商品价格总和
{
	float sum=0;
	for(int i=0;i<count;i++)
		sum +=itemPrice[i];
	cout<<"Total value:"<<sum<<endl;
}
void ITEMS::remove(void)//删除某个商品(将其价格设为0,表示缺货)
{
	int a;
	cout<<"Enter item code:";
	cin>>a;
	for(int i=0;i<count;i++)
	{
		if(itemCode[i]==a)
			itemPrice[i]=0;
	}
}
void ITEMS::displayItems(void)//显示所有商品的详细信息
{
	cout<<"Code Price"<<endl;
	for(int i=0;i<count;i++)
	{
		cout<<"\n"<<itemCode[i]
		<<"    "<<itemPrice[i];
	}
	cout<<endl;
}
int main()
{
	ITEMS order;
	order.CNT();
	int x;
	do
	{
		cout<<"\nYou can do the following;Enter appropriate number"<<endl;//提示命令操作
		cout<<"1.Add an item"<<endl;
		cout<<"2.Display total value"<<endl;
		cout<<"3.Delete an item"<<endl;
		cout<<"4.Display all items"<<endl;
		cout<<"5.Quit"<<endl;
		cout<<"What is your option?"<<endl;
		cin>>x;
		switch(x)//利用switch语句来进行操作命令的选择
		{
			case 1: order.getitem();break;//注意,使用switch时,每一种情况下都要用一个“break”
			case 2: order.displaySum();break;
			case 3: order.remove();break;
			case 4: order.displayItems();break;
			case 5: break;
			default : cout<<"Error in input;try again"<<endl;//必须要有“default”语句,对不满足情况的进行处理
		}
	}
	while(x!=5);//使用do...while来控制循环的结束,即当x=5时结束程序运行
	return 0;
}

上述程序通过定义一个类,该类使用数组作为数据成员,实现了对商品的诸多细节性操作,如添加商品、删除商品、打印订单的总价钱等。

/程序4.静态类成员
#include<iostream>
using namespace std;
class item
{
	static int count;//静态类成员的声明,关键词static
	int number;
public:
	void getdata(int a)
	{
		number=a;
		count++;
	}
	void getcount(void)
	{
		cout<<"count:";
		cout<<count<<endl;
	}
};
int item::count;//静态数据成员的定义
//每个静态成员变量的类型和作用域都定义于类的定义之外
int main()
{
	item a,b,c;
	a.getcount();
	b.getcount();
	c.getcount();

	a.getdata(100);
	b.getdata(200);
	c.getdata(300);

	cout<<"After reading data"<<endl;

	a.getcount();
	b.getcount();
	c.getcount();//三个对象共享了一个count(此为静态变量),所以最后输出值都相等

	return 0;
}

静态类成员的性质:1.被创建时,初始化为0;2.静态成员只有一个实例,无论创建多少泪对象,它们都共享这一静态成员变量;//3.静态成员只在类内可见,其生存期为程序整个执行期。

/程序5.静态成员函数
#include<iostream>
using namespace std;
class test
{
	int code;
	static int count;//声明静态成员变量
public:
	void setcode(void)
	{
		code=++count;
	}
	void showcode(void)
	{
		cout<<"object number:"<<code<<endl;
		//cout<<"object number:"<<count<<endl;
	}
	static void showcount(void)//静态成员函数的定义
	{
		cout<<"count:"<<count<<endl;//在这里,静态函数只能调用静态成员变量count,若调用code则出错
	}
};
int test::count;//静态数据成员的定义
int main()
{
	test t1,t2;//创建类对象t1,t2
	t1.setcode();//调用类成员函数setcode
	t2.setcode();

	test::showcount();//静态成员函数的调用,使用类名调用

	test t3;
	t3.setcode();

	test::showcount();

	t1.showcode();
	t2.showcode();
	t3.showcode();//三个变量各有自已的code副本,所以最后值各不相同

	return 0;
}

静态成员函数的特性:1.只能访问类内声明的其它静态成员;2.使用类名调用静态成员函数

/程序6.对象数组
#include<iostream>
using namespace std;
class employee//类employee的声明
{
	char name[30];//类内数组
	float age;
public:
	void getdata(void);
	void putdata(void);
};
void employee::getdata(void)//类成员函数getdata的定义
{
	cout<<"Enter name:";
	cin>>name;
	cout<<"Enter age:";
	cin>>age;
}
void employee::putdata(void)//类成员函数putdata的定义
{
	cout<<"Name:"<<name<<endl;
	cout<<"Age:"<<age<<endl;
}
const int size=3;//定义一个整形常量,用于表示数组大小
int main()
{
	employee manager[size];//定义了大小为size的类manager对象数组
	for(int i=0;i<size;i++)
	{
		cout<<"\nEnter details of manager"<<i+1<<endl;//输入每个类对象的内容
		manager[i].getdata();
	}
	cout<<endl;
	for(int i=0;i<size;i++)
	{
		cout<<"Manager"<<i+1<<endl;//显示每个类对象的内容
		manager[i].putdata();
		cout<<endl;
	}
	return 0;
}
程序7.对象参数,即将对象作为函数的参数
//两种方法:1.传值:对象的整个副本传递给函数;2.传引用:只传递对象的地址
#include<iostream>
using namespace std;
class time//类time的声明
{
	int hours;
	int minutes;
public:
	void gettime(int h,int m)//类内定义gettime函数
	{
		hours=h;
		minutes=m;
	}
	void puttime(void)//类内定义puttime函数
	{
		cout<<hours<<" hours and ";
		cout<<minutes<<" minutes "<<endl;
	}
	void sum(time,time);//声明成员函数sum,其中函数的参数为类time的对象
};
void time::sum(time t1,time t2)//sum函数的定义,t1、t2都是对象
{
	minutes=t1.minutes+t2.minutes;
	hours=minutes/60;
	minutes=minutes%60;
	hours=hours+t1.hours+t2.hours;
}
int main()
{
	time T1,T2,T3;
	T1.gettime(2,45);
	T2.gettime(3,30);
	T3.sum(T1,T2);//对象T3调用sum函数,对象T1、T2作为参数
	cout<<"T1=";
	T1.puttime();
	cout<<"T2=";
	T2.puttime();
	cout<<"T3=";
	T3.puttime();
	return 0;
}

因为传引用时只需拷贝对象的地址,而不用吧整个对象复制过去,所以传引用方法的效率更高。

//程序8.友元函数
//声明为友元函数可以对类的私有数据有完全的访问权限
#include<iostream>
using namespace std;
class sample//声明类sample
{
	int a;
	int b;
public:
	void setvalue() //设置a、b的值
	{
		a=25;
		b=40;
	}
	friend float mean(sample s);//声明一个友元函数,格式:关键词(friend)+返回类型+函数名(参数列表)
//一个函数可以在任意多个类中声明为友元。};
float mean(sample s)//友元函数定义时不用加关键词friend,也不用使用作用域操作符::
{
	return float(s.a+s.b)/2.0;//通过对象变量和点操作符,访问类变量a和b
}
int main()
{
	sample X;
	X.setvalue();
	cout<<"Mean value="<<mean(X)<<endl;//对象X按传值法传递给友元函数

	return 0;
}

特别要注意的是,友元函数和常规函数一样,不使用对象进行调用;可以声明在类的公共或私有部分。

/程序9.两个类的一个友元函数
//通过友元函数来连接两个类
#include<iostream>
using namespace std;
class ABC;//前置声明
class XYZ
{
	int x;
public:
	void setvalue(int i)
	{
		x=i;
	}
	friend void max(XYZ,ABC);//在两个类中都要声明该友元函数
};
class ABC
{
	int a;
public:
	void setvalue(int i)
	{
		a=i;
	}
	friend void max(XYZ,ABC);//在两个类中都要声明该友元函数
};
void max(XYZ m,ABC n)//友元函数的定义,不用再加关键词friend或类名
{
	if(m.x>n.a)
	{
		cout<<m.x;
	}
	else
	{
		cout<<n.a;
	}
}
int main()
{
	XYZ xyz;//创建类对象
	xyz.setvalue(20);//调用类XYZ成员函数setvalue
	ABC abc;
	abc.setvalue(10);

	max(xyz,abc);//调用友元函数
	cout<<endl;
	return 0;
}

上述程序体现了不同的两个类中定义同一个友元函数,以此来连接两个类。

/程序10.交换类的私有数据
#include<iostream>
using namespace std;
class v1;//类v1的前置声明
class v2//类v2的定义
{
	int value1;//创建类成员变量
public:
	void indata(int a )//类内声明、定义成员函数
	{
		value1=a;
	}
	void display(void)
	{
		cout<<value1<<endl;
	}
	friend void exchange(v1 &,v2 &);//友元函数的声明,关键词friend
};
class v1
{
	int value2;
public:
	void indata(int a)
	{
		value2=a;
	}
	void display(void)
	{
		cout<<value2<<endl;
	}
	friend void exchange(v1 &,v2 &);
};
void exchange(v1 &x,v2 &y)//友元函数的定义,不用加关键词friend,也不用使用类名和作用域解析符::
{
	int temp=x.value2;
	x.value2=y.value1;//这是一个传引用函数的友元函数
	y.value1=temp;
}
int main()
{
	v1 c1;//创建类对象
	v2 c2;
	c1.indata(100);//调用类成员函数
	c2.indata(500);
	cout<<"Values before exchange"<<endl;//提示输出的内容
	c1.display();
	c2.display();
	exchange(c1,c2);//直接调用友元函数,实现私有数据的交换
	cout<<"Values after exchange"<<endl;
	c1.display();
	c2.display();
	return 0;
}

上述程序利用友元函数传引用参数,来改变类的私有数据值。

//程序11.返回对象
#include<iostream>
using namespace std;
class complex//类complex的声明与定义
{
	float x;
	float y;
public:
	void input(float real,float imag)//类内定义成员函数input
	{
		x=real;
		y=imag;
	}
	friend complex sum(complex,complex);//友元函数
	void show(complex);
};
complex sum(complex c1,complex c2)//对象作为参数
{
	complex c3;
	c3.x=c1.x+c2.x;
	c3.y=c1.y+c2.y;
	return (c3);//返回对象c3
}
void complex::show(complex c)
{
	cout<<c.x<<"+j"<<c.y<<endl;
}
int main()
{
	complex a,b,c;
	a.input(3.1,5.65);
	b.input(2.75,1.2);
	c=sum(a,b);
	cout<<"a=";
	a.show(a);
	cout<<"b=";
	b.show(b);
	cout<<"c=";
	c.show(c);
	return 0;
}

上述程序说明了函数不仅可以接受对象参数,也可以返回对象。

程序12.取值符,当使用对象和成员的指针时,用取值符->*来访问成员;当在对象中使用了成员指针时,则用取值符.*
//可以使用&操作符来获取成员的地址,
//声明一个类成员指针时,可以使用类名和操作符::*
#include<iostream>
using namespace std;
class M
{
	int x;
	int y;
public:
	void set_xy(int a,int b)
	{
		x=a;
		y=b;
	}
	friend int sum(M m);
};
int sum(M m)
{
	int M::* px=&M::x;//指针px被创建后,必须使用类对象才能调用,&M::x表示:类M的成员x的地址
	int M::* py=&M::y;//M::*表示:指向类M的成员的指针,&M::y表示:类M的成员y的地址
	M *pm=&m;//pm为对象m的指针
	int S=m.*px+pm->*py;//m.*px等价于m.x;pm->*py等价于pm->y
	return S;
}
int main()
{
	M n;
	void (M:: *pf)(int,int)=&M::set_xy;//成员函数指针
	(n.*pf)(10,20);//成员指针pf
	cout<<"SUM="<<sum(n)<<endl;
	M *op=&n;//对象指针op
	(op->*pf)(30,40);
	cout<<"SUM="<<sum(n)<<"\n";
	return 0;
}

成员指针这是比较重要的,要区分好类成员指针(如,M::* py&M::y)与对象指针(如,n=&n)








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值