一个程序的调试过程

作者: 天涯无情 @ 09/10 2006, 08:46

  学习数据结构的集合,根据范例程序写了一个例子:

头文件是: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,装完立马运行,编译通过!将头文件的实现也改成最开始的函数实现,也没有提示不能访问私有成员的错误了!

晕倒,折腾了半天原来是微软的软件问题。



  © 感知世界,感知未来, All rights reserved.