undefined reference to *** —— 类成员

undefined reference to *** —— 类成员
2009-05-09 14:13
undefined reference to ***这个链接错误的花样总是层出不穷( more),这一次是找不到类中的成员。

例子1:undefined reference to VS. 类静态成员变量

在文件hAB.h中声明了类A与类B:
class A
{
     public:
         void funA();
}

class B
{
     public:
          void funB();
     private:
           static A *pa;                  // 注:这里把成员变量声明为static
}

文件fA.cpp实现类A:
void A::funA()
{
     printf("I am funA()\n");
}

文件fB.cpp实现类B:
void B::funB()
{
     pa = new A();
     pa->funA();
}

文件fM.cpp实现main函数:
int main(int argc, char *argv[])
{
     B *pb = new B();
     pb->funB();
     return 0;
}

Makefile:先生成fA.o与fB.o,然后打包为libtest.a;再生成fM.o,最后用“g++ fM.o -ltest -o fM”把目标文件链接起来并生成可执行文件fM。

问题:
gcc返回链接错误:undefined reference to 'B::pa'。然而,把类B中的pa声明为非static变量,则可以通过编译。

WHY:
先复习一下static data members in class。
[1] a  single piece of storage for a static data member,  regardless of how many objects of that class you create.
[2] the static data belongs to the class. Its name is scoped inside the class and all objects share that data member.
[3] NOTE: The linker will report an error  if a static data member is declared but not defined.

所以,问题就出在:在class中,无法对static data member进行复制,即便是在构造函数中对static data member进行赋值,linker还是会报错。
因为static data member不属于任何一个对象,所以即便是在创建对象的时候进行赋值,也只能说明,这个对象对这个data member重新赋值而已。
因此,这里的undefined reference to ***,是找不到类静态成员变量的定义。

解决方法:
The definition must occur outside the class (no inlining is allowed), and only one definition is allowed.
It is common to put it in the implementation file for the class.
其实,也就是在 全局的地方对静态成员变量赋值。

在上面的例子中,可在文件fB.h中加上pa的定义:
A *B::pa = new A();

----------------------------------------------------------------------------------------------------------------------------------

例子2:undefined reference to VS. 虚函数

在文件hAB.h中声明了类A与类B:
class A
{
     public:
          virtual void fun();
}

class B :  public A
{
     public:
          void fun();
}

文件fB.cpp实现类B:
void B::fun()
{
     printf("I am B::fun()\n");
}

文件fM.cpp实现main函数:
int main(int argc, char *argv[])
{
     A *pa = new B();
     pa->fun();
     return 0;
}

问题:
gcc返回链接错误:undefined reference to 'vtable for A'。
这是因为(个人认为),编译器在建立虚函数表的时候,找不到A::fun()在.text segment中的地址,所以便无法完成虚函数表的创建。

解决方法:
1] 实现A::fun()
2] 将A::fun()声明为纯虚函数,也就是virtual void fun() = 0;

你可能感兴趣的:(gcc,Class,makefile,reference,fun,linker)