C++对类中字符串成员进行初始化的两种方法以及友元函数的使用

       在C++之中,如果要建立一个类,且类中需要有字符串数据成员,我们可以把该成员声明成两种类型。

      第一种方法:使用头文件string,把字符串数据成员声明为string类的对象,用这种方法对字符串操作十分便捷,可以通过+、=、+=、==等等运算符对字符串进行拼接或判断。

      第二种方法:直接把该数据成员声明为const char*类型,即一个指针。在这种情况下,一系列操作就相对麻烦,不过也能顺利得出结果。

       代码示例:

//类中字符串成员进行初始化的两种方法以及友元函数的使用
#include<string>
#include<iostream>
using namespace std;
class GIRLS;//提前引用声明,因为声明友元函数output()在声明GIRLS之前
class BOYS {
private:
	char* name;      //姓名
	int age;         //年龄
	char* country;   //国籍
	static int count;//累计人数
public:
	BOYS(const char* n, int a, const char* c);/*第一种初始化字符串的方法,即用const char* 指针,
	                                          注意const不能少,否则会报错*/
	~BOYS();                                  //用到指针必然要分配地址,注意把分配到地址消除掉
	friend void output(BOYS&,GIRLS&);
};
class GIRLS {
private:
	string name;                             //注意,与BOYS中不同,将name声明为string类的对象  
	int age;         
	string country;                          //注意,与BOYS中不同,将country声明为string类的对象   
	static int count;
public:
	GIRLS(string n,int a, string c);/*第二种初始化字符串的方法,即将字符串类型声明为string类的对象*/                                    
	/*    ~GIRLS()这个析构函数在这里可以不需要显示声明,用自动生成的隐式析构函数即可   */
	friend void output(BOYS&,GIRLS&);
};
//以上类的声明可以换一种方式,如声明一个基类student作为模板,再声明BOYS,GIRLS对基类student进行继承,
//但是这里我们要分别演示
BOYS::BOYS(const char* n, int a, const char* c) {
	name = new char[strlen(n) + 1];//+1是为了存放字符串末尾的空字符
	strcpy(name, n);
	age = a;
	country = new char[strlen(c) + 1];
	strcpy(country, c);
	count++;
}
BOYS::~BOYS() {
	delete []name;
	delete []country;
}
GIRLS::GIRLS(string n,int a, string c) //因为在GIRLS类中把name与country声明为string类,这里的构造函数也相应地不同
{
	name = n;
	age = a;
	country = c;
	count++;
}
void output(BOYS& b, GIRLS& g) {
	cout << "boys:\nname:" << b.name << " age:" << b.age << " country:" << b.country <<" count:" <<b.count<< endl;
	cout << "girls:\nname:" << g.name << " age:" << g.age << " country:" << g.country <<" count:" << b.count << endl;
}
int BOYS::count = 0;//初始化静态数据成员
int GIRLS::count = 0;
int main() {
	string inname2[6], incountry2[6];//建立string类对象数组存放将要输入给女生的string类数据类型成员的内容
	int inage2[6];//女生年龄
	cout << "Now input the information of girls" << endl;
	for (int i = 0; i < 6; i++)
		cin >> inname2[i] >> inage2[i] >> incountry2[i];
	BOYS boys[6]{
	BOYS("Peter",19,"America"),
	BOYS("Martin",20,"England"),
	BOYS("Mask",18,"Germany"),
	BOYS("Zhang He",18,"China"),
	BOYS("Wang Wei",19,"China"),
	BOYS("Alan",20,"Poland")
	};
	GIRLS girls[6]{
		GIRLS(inname2[0],inage2[0],incountry2[0]),
		GIRLS(inname2[1],inage2[1],incountry2[1]),
		GIRLS(inname2[2],inage2[2],incountry2[2]),
		GIRLS(inname2[3],inage2[3],incountry2[3]),
		GIRLS(inname2[4],inage2[4],incountry2[4]),
		GIRLS(inname2[5],inage2[5],incountry2[5])
	};
	for(int i=0;i<6;i++)
		output(boys[i], girls[i]);
	return 0;
}

当然,使用const char*类型,我原本是想从输入流来导入BOYS对象的数据,但是当我建立了指针数组并想把输入流的字符串赋予它时,却出现了问题。这下面的代码段是我原来的设想:

    int inage1[6];//年龄
	char *inname1[6], *incountry1[6];//建立char*类型的指针数组存放将要输入给男生的char*类型数据成员的内容
	cout << "Firstly input the information of boys" << endl;
	for (int i = 0; i < 6; i++)
		cin >> inname1[i] >> inage1[i] >> incountry1[i];//visual stdio2019此处报错,显示为使用没有初始化的内存inname[i],incountry[i];
	BOYS boys[6]{
		BOYS(inname1[0], inage1[0], incountry1[0]),//由于男生的构造函数中的形参为char*,int,char*,用string,int,string
		BOYS(inname1[1], inage1[1], incountry1[1]),//类作为实参则会报错,表示找不到匹配的构造函数,所以要另外为男生建立
		BOYS(inname1[2], inage1[2], incountry1[2]),//char*类型数组来存放输入与调用构造函数,这点十分重要
		BOYS(inname1[3], inage1[3], incountry1[3]),
		BOYS(inname1[4], inage1[4], incountry1[4]),
		BOYS(inname1[5], inage1[5], incountry1[5])
	};

在处理输入时显示我使用了未初始化的内存inname[i],incountry[i].

于是我只好先用示例中的方法处理boys这个对象的初始化,不过终归是可以运行了,结果如下:

Now input the information of girls
张小丽 18 China
Lisa 19 America
Pepper 20 America
Jane 18 England
Marry 19 France
陈芳 20 China
boys:
name:Peter age:19 country:America count:6
girls:
name:张小丽 age:18 country:China count:6
boys:
name:Martin age:20 country:England count:6
girls:
name:Lisa age:19 country:America count:6
boys:
name:Mask age:18 country:Germany count:6
girls:
name:Pepper age:20 country:America count:6
boys:
name:Zhang He age:18 country:China count:6
girls:
name:Jane age:18 country:England count:6
boys:
name:Wang Wei age:19 country:China count:6
girls:
name:Marry age:19 country:France count:6
boys:
name:Alan age:20 country:Poland count:6
girls:
name:陈芳 age:20 country:China count:6

人数统计这个点上,我没有设计好,应该再多写个成员函数打印一次总人数即可,不需要打印出这么多次count。

在我的多次尝试之下,我发现了前面提到的报错的一个解决方法:

把“char *inname1[6], *incountry1[6];”这个语句改为“char inname1[6][30], incountry1[6][30];”,这样输入流就能接收我输入的长度小于30的字符串(中间无空格,有空格的话会出错),即:

    int inage1[6];
	char inname1[6][30], incountry1[6][30];//修正的结果
	cout << "Firstly input the information of boys" << endl;
	for (int i = 0; i < 6; i++)
		cin >> inname1[i] >> inage1[i] >> incountry1[i];
	BOYS boys[6]{
		BOYS(inname1[0], inage1[0], incountry1[0]),//对二维数组而言,诸如inname[i],incountry[i]都是地址常量,故能匹配上BOYS的构造函数对形参是const char*的要求
		BOYS(inname1[1], inage1[1], incountry1[1]),
		BOYS(inname1[2], inage1[2], incountry1[2]),
		BOYS(inname1[3], inage1[3], incountry1[3]),
		BOYS(inname1[4], inage1[4], incountry1[4]),
		BOYS(inname1[5], inage1[5], incountry1[5])
	};

  • 22
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值