目录
自定义数据类型在容器中的正确操作形式
在一些情况下自定义数据类型变量一定要声明为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;
}
结果显示