自定义数据类型在容器中的正确操作形式

目录

自定义数据类型在容器中的正确操作形式

在一些情况下自定义数据类型变量一定要声明为const类型的

将自定义数据类型声明为const类型的情况

代码示例

输出错误显示

疑问解答

错因分析

解决方法

综合代码示例

同样适用于vector数组

基本数据类型也不例外

很难发现的原因

代码示例

结果显示


自定义数据类型在容器中的正确操作形式

在一些情况下自定义数据类型变量一定要声明为const类型的

将自定义数据类型声明为const类型的情况

① 重载运算符的形参;

② 默认set容器排序函数的形参;

注:只要是涉及排序等不改变容器内元素值得操作,均将参数声明为const类型,声明形式如下:

 

代码示例

#include <iostream>  
#include <sstream>  
#include <string>  
#include <set>  
using namespace std;  
  
struct Student  
{  
    string name;  
    int StudNumber;  
    string OutputString;  
  
    Student(string name, int StudNumber)  
    {  
        this->name = name;  
        this->StudNumber = StudNumber;  
    }  
    operator const char* ()  
    {  
        ostringstream Output;  
        Output << this->name << "的学号为" << this->StudNumber << endl;  
        OutputString = Output.str();  
        return OutputString.c_str();  
    }  
};  
  
int main()  
{  
    Student stud1("张三", 1), stud2("李四", 2), stud3("王五", 3), stud4("赵六", 4);  
    set<Student> Stud{ stud1,stud2,stud3,stud4 };  
    set<Student>::iterator itor = Stud.begin();  
    cout << *itor << endl;  
}  

 

输出错误显示

 

疑问解答

有些同学问:“无不是已经重载了const char*了吗?按道理来讲”cout<<自定义数据类型对象”应该发生了隐式数据类型转换才对呀?”,那让我们看下列代码:

#include <iostream>  
#include <sstream>  
#include <string>  
#include <set>  
using namespace std;  
  
struct Student  
{  
    string name;  
    int StudNumber;  
    string OutputString;  
  
    Student(string name, int StudNumber)  
    {  
        this->name = name;  
        this->StudNumber = StudNumber;  
    }  
    explicit operator const char* () // 使用explicit禁止隐式数据类型转换  
    {  
        ostringstream Output;  
        Output << this->name << "的学号为" << this->StudNumber << endl;  
        OutputString = Output.str();  
        return OutputString.c_str();  
    }  
};  
  
int main()  
{  
    Student stud1("张三", 1), stud2("李四", 2), stud3("王五", 3), stud4("赵六", 4);  
    set<Student> Stud{ stud1,stud2,stud3,stud4 };  
    set<Student>::iterator itor = Stud.begin();  
    cout << *itor << endl;  
}  

 

代码中显示的错误是:

 

按道理来讲“explicit禁止了隐式转换,运行上述程序时应该会在cout<<自定义数据类型的对象“这里报错才对呀?但是还是这两个错误,说明根本没有发生const char*隐式类型转换。

错因分析

大家会问到:“这是为什么呀?“,因为iterator迭代器所指向的对象都是const类型的,而你重载的const char*操作对象是非const类型的,参数属性不对当然不会调用重载后的类型转换符了。

#include <iostream>  
#include <sstream>  
#include <string>  
#include <set>  
using namespace std;  
  
struct Student  
{  
    string name;  
    int StudNumber;  
    string OutputString;  
  
    Student(string name, int StudNumber)  
    {  
        this->name = name;  
        this->StudNumber = StudNumber;  
    }  
    operator const char* ()  
    {  
        ostringstream Output;  
        Output << this->name << "的学号为" << this->StudNumber << endl;  
        OutputString = Output.str();  
        return OutputString.c_str();  
    }  
};  
  
int main()  
{  
    Student stud1("张三", 1), stud2("李四", 2), stud3("王五", 3), stud4("赵六", 4);  
    set<Student> Stud{ stud1,stud2,stud3,stud4 };  
    set<Student>::iterator itor = Stud.begin();  
    //cout << *itor << endl;  // 输出不了const类型的自定义数据类型
    cout << stud2 << endl;  // 成功输出非const类型的自定义数据类型
}  

 

解决方法

#include <iostream>  
#include <sstream>  
#include <string>  
#include <set>  
using namespace std;  
  
struct Student  
{  
    string name;  
    int StudNumber;  
    string OutputString;  
  
    Student(string name, int StudNumber)  
    {  
        this->name = name;  
        this->StudNumber = StudNumber;  
    }  
    operator const char* ()  
    {  
        ostringstream Output;  
        Output << this->name << "的学号为" << this->StudNumber << endl;  
        OutputString = Output.str();  
        return OutputString.c_str();  
    }  
    bool operator < (const Student& stud) const // set容器默认进行升序排列调用<重载运算符  
    {  
        return this->StudNumber < stud.StudNumber;  
    }  
    friend ostream& operator << (ostream& Output, Student& stud1);  
};  
ostream& operator << (ostream& Output, const Student& stud1)  
{  
    Output << stud1.name << "的学号为" << stud1.StudNumber << endl;  
    return Output;  
}  
  
int main()  
{  
    Student stud1("张三", 1), stud2("李四", 2), stud3("王五", 3), stud4("赵六", 4);  
    set<Student> Stud{ stud1,stud2,stud3,stud4 };  
    set<Student>::iterator itor = Stud.begin();  
    cout << *itor << endl;  
}  

 

重载<<运算符,但是这里面要注意, <<,>……等一些列针对于自定义数据类型的重载运算符的参数一定要声明为const类型。

综合代码示例

// set容器易错点.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。  
//  
  
#include <iostream>  
#include <sstream>  
#include <string>  
#include <set>  
using namespace std;  
  
struct Student  
{  
    string name;  
    int StudNumber;  
    string OutputString;  
  
    Student(string name, int StudNumber)  
    {  
        this->name = name;  
        this->StudNumber = StudNumber;  
    }  
    operator const char* ()  
    {  
        ostringstream Output;  
        Output << this->name << "的学号为" << this->StudNumber << endl;  
        OutputString = Output.str();  
        return OutputString.c_str();  
    }  
    bool operator < (const Student& stud) const // set容器默认进行升序排列调用<重载运算符  
    {  
        return this->StudNumber < stud.StudNumber;  
    }  
    bool operator == (const string& name) const  
    {  
        return this->name == name;  
    }  
    friend ostream& operator << (ostream& Output, Student& stud1);  
};  
ostream& operator << (ostream& Output, const Student& stud1)  
{  
    Output << stud1.name << "的学号为" << stud1.StudNumber << endl;  
    return Output;  
}  
  
int main()  
{  
    Student stud1("张三", 1), stud2("李四", 2), stud3("王五", 3), stud4("赵六", 4);  
    set<Student> Stud{ stud1,stud2,stud3,stud4 };  
    set<Student>::iterator itor = find(Stud.begin(), Stud.end(), "李四");  
    cout << *itor << endl;  
}

  

注意:这里的find函数返回值是指向const类型变量的迭代器。

 

同样适用于vector数组

#include <iostream>
#include <vector>
#include <sstream>
#include <string>
using namespace std;

struct Student
{
	string name;
	int StudNumber;
	string OutputString;

	Student(string name, int StudNumber)
	{
		this->name = name;
		this->StudNumber = StudNumber;
	}
	bool operator == (const Student& stud)
	{
		return this->name == stud.name;
	}
	bool operator == (const int& StudNumber)
	{
		return this->StudNumber == StudNumber;
	}
	bool operator == (const string& name)
	{
		return this->name == name;
	}
	bool operator > (Student& stud)
	{
		return this->StudNumber > stud.StudNumber;
	}
	friend ostream& operator << (ostream& output, Student& stud);
};
ostream& operator << (ostream& output, Student& stud)
{
	output << stud.name << "的学号为" << stud.StudNumber << endl;
	return output;
}
int main()
{
	Student stud1("张三", 1), stud2("李四", 2), stud3("王五", 3), stud4("赵六", 4);
	vector<Student> Stud = { stud1,stud2,stud3,stud4 };
	vector<Student>::iterator itor = find(Stud.begin(), Stud.end(), stud3);
	if (itor != Stud.end())
	{
		cout << *itor << endl;
	}
	else
	{
		cout << "超出索引范围" << endl;
	}
	itor = find(Stud.begin(), Stud.end(), 2);
	if (itor != Stud.end())
	{
		cout << *itor << endl;
	}
	else
	{
		cout << "超出索引范围" << endl;
	}
	itor = find(Stud.begin(), Stud.end(), "张三");
	if (itor != Stud.end())
	{
		cout << *itor << endl;
	}
	else
	{
		cout << "超出索引范围" << endl;
	}
}

 

基本数据类型也不例外

很难发现的原因

由于基本数据类型可以进行隐式类型转换,因此你不会很容易发现。

代码示例

#include <iostream>  
#include <set>  
using namespace std;  
  
int main()  
{  
    set<int> SetArray1{ 1,2,3,4,5 };  
    set<int>::iterator itor1 = SetArray1.begin();  
    cout << *itor1 << endl;  
}  

 

结果显示

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肥肥胖胖是太阳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值