簡體   English   中英

對`typeinfo和'vtable的未定義引用

[英]undefined reference to `typeinfo and 'vtable

我目前正在開發一個使用虛擬功能用戶的程序。 我只使用一個虛函數,並且遇到了一個常見的問題,我嘗試了一個常見的解決方案,但遺憾的是沒有成功。

我最初有虛擬空洞calcArea(); 在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()
{
}

circle.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);
}

Rectangle.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

Rectangle.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);
}

驅動程序是不完整的,但無論如何都與我的問題無關(至少我是這么認為的)。

#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;
}

實際上,正如所指出的那樣,你不必編譯頭文件。 (雖然你可以,但這里無關緊要--- gcc會生成預編譯的頭文件)。

更有趣的是:你的例子完全適用於此,GCC 4.6.3。

另外,旁注:calcArea不應公開

你不應該嘗試編譯標題:

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

您的編譯器至少需要一個轉換單元,其中在每個多態類的類定義之外定義虛擬成員。 只有存在這樣的翻譯單元時,它才會為類(虛函數表,多態類型信息)實例化一些內部數據。

(免責聲明:至少在我上次使用它的情況下,很久以前)

你既可以使用外的類的定義為BasicShape::calcArea功能或虛擬(可選甚至純虛)析構函數添加到BasicShape並將它定義外的類。 最好的地方可能是BasicShape.cpp文件。

順便說一句:正如其他人所指出的那樣,您通常不應將頭文件作為單獨的翻譯單元傳遞給編譯器。 這不會造成任何傷害(除了延長你的編譯時間),但也沒有好處。

好吧,顯然這一切似乎都是編譯問題。 這整個時間我使用gedit作為文本編輯器和g ++作為編譯器,但當我切換到代碼塊時它工作得很好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM