C++学习笔记(1)

来源:互联网 发布:杀破狼 js主唱去世 编辑:程序博客网 时间:2024/06/06 20:49

今天写code的时候,由于想写一些比较general的program,所以用了map和virtual destructor。

  1. 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 声明,但是这种办法有限制,如果在类中使用了循环链中的一个类的函数,那么单单是声明是解决不了问题的。

 

原创粉丝点击