今天写code的时候,由于想写一些比较general的program,所以用了map和virtual destructor。
- map: 使用map的时候,如果key的类型是自定义类型,例如MyClass。由于map需要在内部根据key排序,所以是需要给一个comp函数或者是实现了operator()的类的,那么在使用的时候可以有如下几种定义方法:
<1>类定义里面实现:
class MyClass {
public:
MyClass() : data(0) {}
MyClass(int num) : data(num) {}
bool operator< (const MyClass &o)
{
return data < o.data;
}
bool operator< (const MyClass &o) const
{
return data < o.data;
}
private:
int data;
};
注意这里的operator<函数里面的函数需要带const,函数本身也需要是const。然后在声明map的时候就可以map<MyClass, int>这样声明。
<2>使用比较函数实现:
类定义同上,但是如果不定义operator<的话,那么可以另外定义一个函数:
bool cmpMyClass(const MyClass o1, const MyClass o2)
{
return o1 < o2;
}
也是注意参数需要有const。这样在声明map的时候可以这样声明:
map<MyClass, int, bool (*)(const MyClass, const MyClass)> m(cmpMyClass);
<3>使用比较类的实现:
可以另外定义一个类,这个类定义一个operator(),他的功能就是比较key的两个值:
class CmpMyClass {
public:
bool operator() (const MyClass &o1, const MyClass &o2) const
{
return o1 < o2;
}
};
注意函数里面的参数仍然是要const,函数本身也要是const。在声明map的时候就可以这样声明:
map<MyClass, int, CmpMyClass> m;
2. 在写类的继承的时候,使用了virtual destructor。然后在用g++编译的时候出现了以下的错误:
g++ -Wall -o test test.o problem.o state.o npuzzlestate.o fifoqueue.o node.o
fifoqueue.o: In function `Queue::~Queue()':
FIFOQueue.cpp:(.text._ZN5QueueD2Ev[Queue::~Queue()]+0x7): undefined reference to `vtable for Queue'
fifoqueue.o:(.rodata._ZTI9FIFOQueue[typeinfo for FIFOQueue]+0x8): undefined reference to `typeinfo for Queue'
collect2: ld returned 1 exit status
make: *** [test] Error 1
可以看到在编译的过程没有错误,而是在link的阶段出的错,然后上网查找,有以下几篇相关文章:
http://hi.baidu.com/wind_stay/blog/item/0a2a671ec7ee43ffe1fe0bfc.html
经过修改,我把所有基类里面的virtual function都给了相应的定义。之前是有些virtual function漏了给明确的定义。
所以以后遇到这种情况,如果基类里面的virtual function没有给明确定义的话,可以有两种解决方法:
<1>把定义补上
<2>把函数改成pure virtual的。
3. 在编译的时候,在定义类的头文件里面出现
error: expected class-name before '{' token
的错误,无论怎么检查该类的定义都检查不出错误。
后来在检查include文件的时候,发现这个错误原始是由于我无意中循环的include了一系列的文件。例如如果A include B,B include C,C include A的话,虽然没有直接包含,但是这样在定义类的时候就会出现无法找到类的情况。
一种解决的办法是把循环的include序列截断,另一种办法是在定义的类前面加上class 声明,但是这种办法有限制,如果在类中使用了循环链中的一个类的函数,那么单单是声明是解决不了问题的。