使用虚析构函数会产生错误

Using virtual destructors gives error

本文关键字:错误 析构函数      更新时间:2023-10-16

我在为学校编写一个小程序。我想添加虚拟析构函数类'IObject', 'Square'和'RotatedSquare'。但当我这样做时,它会给出一个错误。在这种情况下是不可能的还是在这里怎么做?下面是我的代码:

接口对象:

#ifndef IOBJECT_H_
#define IOBJECT_H_
#include "Point.h"
class IObject {
public:
    virtual const Point& getPosition()const = 0;
    virtual double getSize()const = 0;
    //virtual ~IObject();
};
#endif

类广场

#ifndef SQUARE_H_
#define SQUARE_H_
#include "IObject.h"
#include "Point.h"
#include <iostream>
class Square : public IObject{
private:
    Point position;
    double size;
public:
    Square(const Point& position, const double size):position(position),size(size){};
    virtual const Point& getPosition() const {return this->position;}
    virtual double getSize() const {return this->size;}
    friend std::ostream& operator<<(std::ostream& out, const Square& s);
    //virtual ~Square();
protected:
    virtual void print(std::ostream& out) const;
};
#endif 
类RotatedSquare

#ifndef ROTATEDSQUARE_H_
#define ROTATEDSQUARE_H_
#include "Square.h"
class RotatedSquare : public Square{
private:
    double angle;
public:
    RotatedSquare(const Point& position, const double size, const double angle): Square(position,size),angle(angle){};
    double getAngle() const {return this->angle;}
    //virtual ~RotatedSquare();
protected:
    virtual void print(std::ostream& out) const;
};
#endif

错误:

Undefined symbols for architecture x86_64:
  "Square::~Square()", referenced from:
      _main in Practice.o
  "vtable for RotatedSquare", referenced from:
      RotatedSquare::RotatedSquare(Point const&, double, double) in Practice.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  "vtable for Square", referenced from:
      Square::Square(Point const&, double) in Practice.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  "vtable for IObject", referenced from:
      IObject::IObject() in Practice.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.

主类:

#include <iostream>
#include "Point.h"
#include "IObject.h"
#include "Square.h"
#include "RotatedSquare.h"
int main() {
     IObject* s1 = new Square(Point(1,4),2.2);
     std::cout << s1->getPosition() << std::endl;
     std::cout << s1->getSize() << std::endl;
  Square s2 = Square(Point(4,5),5);
  Square* s3 = new RotatedSquare(Point(5,5),8,60);
  std::cout << s2 << std::endl;
  std::cout << *s3;
return 0;
}

您需要定义您声明的每个虚析构函数。假设你不希望析构函数做比默认行为更多的事情,你可以通过声明来定义:而不是:

virtual ~IObject();
使用

virtual ~IObject() {}

如果你想在析构函数中做重要的工作,或者通常更喜欢所有的定义都在cpp而不是hpp中,那么在cpp文件中定义析构函数(在hpp中保留没有定义的声明)

IObject::~IObject()
{
// Whatever needs to be done
}

您需要在代码中定义虚析构函数。

"Square::~Square()", referenced from:
      _main in Practice.o
  "vtable for RotatedSquare", referenced from:
      RotatedSquare::RotatedSquare(Point const&, double, double) in Practice.o

注意:虚函数表缺失通常是指第一个非内联虚成员函数没有定义

virtual ~IObject() {}就够了

你的析构函数缺少定义。

如果你不想提供你自己的,你可以简单地使用编译器生成的:

virtual ~X() = default;

这比提供一个空体要好:

virtual ~X() { }

,因为用户提供的1析构函数阻止了类平凡的可析构


1 { /* anything */ }由用户提供,= default不由用户提供。