C++ 未定义对`类型信息和';函数表

C++ 未定义对`类型信息和';函数表,c++,g++,undefined,vtable,typeinfo,C++,G++,Undefined,Vtable,Typeinfo,我目前正在开发一个使用虚拟函数用户的程序。我只使用了一个虚拟函数,遇到了一个常见的问题,我尝试了一个通用的解决方案,但不幸的是没有成功 我最初有一个虚拟的空跟骨();在BasicShape.h中,没有任何定义或指定为纯虚函数。我更改了它并在末尾添加了{}(正如在另一个有类似问题的线程上所建议的那样),但仍然得到以下错误: 我输入: g++ BasicShape.h BasicShape.cpp circle.h circle.cpp Rectangle.h Rectangle.cpp drive

我目前正在开发一个使用虚拟函数用户的程序。我只使用了一个虚拟函数,遇到了一个常见的问题,我尝试了一个通用的解决方案,但不幸的是没有成功

我最初有一个虚拟的空跟骨();在BasicShape.h中,没有任何定义或指定为纯虚函数。我更改了它并在末尾添加了{}(正如在另一个有类似问题的线程上所建议的那样),但仍然得到以下错误:

我输入:

g++ BasicShape.h BasicShape.cpp circle.h circle.cpp Rectangle.h Rectangle.cpp driver.cpp -o Lab4
然后我得到:

/tmp/ccf1Y4Br.o: In function `BasicShape::BasicShape()': circle.cpp:(.text._ZN10BasicShapeC2Ev[_ZN10BasicShapeC5Ev]+0xf): undefined reference to `vtable for BasicShape'
/tmp/ccf1Y4Br.o:(.rodata._ZTI6circle[_ZTI6circle]+0x10): undefined reference to `typeinfo for BasicShape'
/tmp/ccc7gjtH.o:(.rodata._ZTI9Rectangle[_ZTI9Rectangle]+0x10): undefined reference to `typeinfo for BasicShape'
collect2: error: ld returned 1 exit status
有什么想法吗

这是实现文件BasicShape.h:

#ifndef BASICSHAPE_H
#define BASICSHAPE_H

class BasicShape 
{
  protected: 
    double area;

  public:
    double getArea() const;
     virtual void calcArea();
};

#endif
随附的BasicShape.cpp文件:

#include "BasicShape.h"

double BasicShape::getArea() const
{
  return area;
}

void BasicShape::calcArea()
{
}
圆圈h:

#include "BasicShape.h"

#ifndef CIRCLE_H
#define CIRCLE_H

class circle : public BasicShape
{
  private:
    long centerX;
    long centerY;
    double radius;

  public:
    circle(long, long, double);
    long getCenterX() const;
    long getCenterY() const;
    virtual void calcArea();
};

#endif
circle.cpp:

#include "circle.h"

// constructor
circle::circle(long userIn, long userIn2, double userIn3)
{
  centerX = userIn;
  centerY = userIn2;
  radius = userIn3;
  calcArea();
}

// accesors
long circle::getCenterX() const
{
  return centerX;
}

long circle::getCenterY() const
{
  return centerY;
}

// virtual function
void circle::calcArea()
{
  area = (3.14159 * radius * radius);
}
矩形.h

#include "BasicShape.h"

#ifndef RECTANGLE_H
#define RECTANGLE_H

class Rectangle : public BasicShape
{
  private:
    long width;
    long length;

  public:
    Rectangle(long, long);
    long getWidth() const;
    long getLength() const;
    virtual void calcArea();
};

#endif
矩形.cpp:

#include "Rectangle.h"

// constructor
Rectangle::Rectangle(long userIn, long userIn2)
{
  width = userIn;
  length = userIn2;
  calcArea();
}

// accessors
long Rectangle::getWidth() const
{
  return width;
}

long Rectangle::getLength() const
{
  return length;
}

void Rectangle::calcArea()
{
  area = (length * width);
}
驱动程序不完整,但与我的问题无关(至少我这么认为)

#包括
#包括
#包括“基本形状h”
#包括“矩形.h”
#包括“circle.h”
使用名称空间std;
int main()
{

cout您不应该尝试编译标题:

g++BasicShape.cpp circle.cpp Rectangle.cpp driver.cpp-o Lab4


您不应尝试编译标题:

g++BasicShape.cpp circle.cpp Rectangle.cpp driver.cpp-o Lab4


事实上,正如前面所指出的,您不必编译头(虽然可以,但在这里并不重要——gcc将生成预编译头)

更有趣的是:您的示例在这里非常有效,GCC4.6.3


另外,旁注:Calcrea不应该是公共的

事实上,正如前面所指出的,您不必编译头(虽然可以,但在这里并不重要---gcc将生成预编译头)

更有趣的是:您的示例在这里非常有效,GCC4.6.3


另外,旁注:Calcrea不应该是公共的

如果在每个多态类的类定义之外定义了虚拟成员,则编译器至少需要一个翻译单元。只有在存在此类翻译单元的情况下,它才会实例化类的一些内部数据(虚拟函数表、多态类型信息)

(免责声明:至少我上次使用它时是这样,很久以前)

您可以为
BasicShape::calcrea
函数使用类外定义,也可以向
BasicShape
添加一个虚拟(甚至是纯虚拟)析构函数,并在类外定义它。最好的位置可能是
BasicShape.cpp
文件


顺便说一句:正如其他人所指出的,您通常不应该将头文件作为单独的翻译单元传递给编译器。这不会造成任何伤害(除了增加编译时间),但也不好。

您的编译器需要至少一个转换单元,其中在每个多态类的类定义之外定义了虚拟成员。仅当存在此类转换单元时,它才会实例化该类的一些内部数据(虚拟函数表、多态类型信息)

(免责声明:至少我上次使用它时是这样,很久以前)

您可以为
BasicShape::calcrea
函数使用类外定义,也可以向
BasicShape
添加一个虚拟(甚至是纯虚拟)析构函数,并在类外定义它。最好的位置可能是
BasicShape.cpp
文件



顺便说一句:正如其他人所指出的,您通常不应该将头文件作为单独的翻译单元传递给编译器。这不会造成任何伤害(除了增加编译时间),但也不好。

好的,显然这一切似乎都是一个编译器问题。这段时间我一直使用gedit作为文本编辑器,g++作为编译器,但当我切换到代码块时,它工作得很好。

好的,所以显然这一切似乎都是一个编译器问题。这段时间我一直使用gedit作为文本编辑器,g++作为编译器一个编译器,但当我切换到代码块时,它工作得很好。

我想你应该首先尝试陈述你的完整问题(包括错误消息、你期望的内容等)在用巨大的代码文件吓跑人们之前。是的,现在我开始考虑这个问题,这看起来确实有点危险。你应该首先尝试陈述你的全部问题(包括错误消息,你期望什么等等)在用巨大的代码文件吓跑人们之前。是的,现在我开始想到它,它看起来确实有点危险,因为tipI只是试图用这种方式编译它,但我得到了同样的结果error@billz:这不会导致链接错误。它只是有时会导致执行哪个函数时出现意外。我只是尝试用这种方式编译它但是我得到了同样的结果error@billz:这不会导致链接错误。它只是有时会导致执行哪个函数时出现意外。所以您认为这可能是g++(我的编译器)独有的问题?@newwarrior21:我认为更可能是你无意中没有提到你的代码中的一些细微差别,或者你试图编译它时做了什么。(这些文件都在同一个目录中,都保存了,等等。)嗯,看起来你的编译器无法处理构造函数中的虚拟函数(默认情况下这是件坏事)。我建议如下修改您的代码:使area易失性,在BasicShape()中将其初始化为-1;在所有嵌套的getArea()方法中,只需检查area是否根本没有缓存(area=-1),然后重新计算该值。类似于
double circle::getArea(){if(-1==area)Calcrea();return area;}
对前面消息的一点修改:
double circle::getArea()const{…}
如果你让
区域
不稳定,那么这段代码就可以很好地工作。简单地说,
区域
不是对象状态的一部分,所以我们是否在const方法中更改它并不重要:)。当你做了这样的设计更改时,你会得到一些好处:你只需要在需要时才需要计算面积。MPogoda:我想你平均值
可变
,而非
挥发性
#include <cassert>
#include <iostream>
#include "BasicShape.h"
#include "Rectangle.h"
#include "circle.h"
using namespace std;

int main()
{

  cout << "Testing the functionality and efficiency of the circle class...\n";
  // declare circle object and test accessors and area computation
  circle objCircle(8,8,4);
  assert(objCircle.getCenterX() == 8);
  assert(objCircle.getCenterY() == 8);
  assert(objCircle.getArea() == 50.26544);
  cout << "Circle object testing completed successfully\n";

  cout << "Testing the functionality and efficiency of the Rectangle class...\n";
  // declare rectangle object and test accessors and area computation  
  //Rectangle objRec();

  return 0;
}