学习数据结构的集合,根据范例程序写了一个例子:
头文件是:product.h,内容如下:
#include <string>
using namespace std;
class products
{
public:
products(const string& com = "", const string& nm = ""):company(com),name(nm){} //构造函数
string getCompany() const; //获取生产公司名
string getName() const; //获取产品名字
friend bool operator< (const products& lhs, const products& rhs);
friend bool operator== (const products& lhs, const products& rhs);
private:
string company;
string name;
};
//函数的实现如下:
string products::getCompany() const
{
return company;
}
string products::getName() const
{
return name;
}
bool operator< (const products& lhs, const products& rhs);
{
return lhs.company < rhs.company;
}
bool operator== (const products& lhs, const products& rhs);
{
return lhs.company == rhs.company;
}
//----------头文件的定义结束----------
主函数的程序如下:
#include <iostream>
#include <set>
#include "product.h"
using namespace std;
void main(void)
{
products proArr[] = {products("Microsoft", "word"), products("Inprise", "C++ Builder"),products("Microsoft", "Excel"),}; //声明一个products数组
int arrSize = sizeof(proArr)/sizeof(products); //获取数组中products的个数
multiset <products> software(proArr, proArr + arrSize); //初始化多重集合
cout << "Number of software productss = " << software.size() << endl;//打印集合的个数
}
//主函数结束
编译,发现不能通过,提示说两个友元重载函数不能访问私有成员.可是友元函数就是用于访问保护成员和私有成员的非成员函数啊!先不管它,毕竟我设计了两个与私有成员交互的接口,因此我将友员函数的实现改为如下:
bool operator< (const products& lhs, const products& rhs);
{
return lhs.getCompany()< rhs.getCompany();
}
bool operator== (const products& lhs, const products& rhs);
{
return lhs.getCompany() == rhs.getCompany();
}
这样总可以了吧?再次编译,还是有一个错误,为什么?仔细看了错误,说是'<'是不确定的(ambiguous),定位错误,却是到了ms vc提供的模板类进去.我就迷糊了:这是什么错误啊?于是开始一步步校对自己的代码.
1.会不会重载'<'和'=='错了?因此决定不加载string类而自己写两个比较函数.
bool compare(string& s1, string& s2);
bool equal(string& s1, string& s2);
bool operator< (const products& lhs, const products& rhs)
{
return compare(lhs.getCompany(), rhs.getCompany());
}
bool operator== (const products& lhs, const products& rhs)
{
return equal(lhs.getCompany(), rhs.getCompany());
}
//s1 < s2 返回true,否则返回false
bool compare(string& s1, string& s2)
{
char *p1 = &s1[0];
char *p2 = &s2[0];
for (int i=0; i< ((s1.length()>s2.length())?s2.length():s1.length()); i++)
{
if (*p1 < *p2)
{
return true;
break;
}
else if (*p1 == *p2)
{
p1++;
p2++;
}
else
{
return false;
break;
}
}
if (s1.length() < s2.length())
return true;
else
return false;
}
//s1 == s2 返回true,否则返回false
bool equal(string& s1, string& s2)
{
if(s1.length() == s2.length())
{
for (int i=0; i< s1.length(); i++)
{
if (s1[i] != s2[i])
{
return false;
break;
}
}
return true;
}
else
return false;
}
再次编译,还是不行!!同样提示'<' is ambigious.而检查了重载函数的代码,没错啊!看来问题不是在头文件了。
2.主函数的内容为空,编译,果然没有错误,因此就逐行定位,发现到
multiset <products> software(proArr, proArr + arrSize); //初始化多重集合
时,就出现了这个错误。为什么初始化会不正确?想了想,集合是在二叉树的基础上构建的,因此在初始化时,就相当于将数据放入到二叉树中,而此间就要设计到proArr数组中各个数据的比较,难道还是'<'的重载时出错了?此时发现自己又踏入了一个死循环中。叫了别人来帮我调试,也不知道是何缘故。浪费了我一晚上的精力啊!!!
今天上午打开电脑,又想到了这个问题,还是不甘心,于是决定彻底弄清friend函数,上网找了一下,耶?竟然也有好多人对friend函数不能访问私有成员的疑问。打开几篇帖子来看,有人说是因为没有ms VC6.0 没有装sp5的缘故。我就想:我的这个问题是不是也有牵连?
立马上网下了sp5,装完立马运行,编译通过!将头文件的实现也改成最开始的函数实现,也没有提示不能访问私有成员的错误了!
晕倒,折腾了半天原来是微软的软件问题。