【问题标题】:Using virtual destructors gives error [duplicate]使用虚拟析构函数会出错[重复]
【发布时间】:2015-08-05 10:41:32
【问题描述】:

我正在为学校制作一个小程序。我想将虚拟析构函数添加到类“IObject”、“Square”和“RotatedSquare”中。但是当我这样做时,它给出了一个错误。在这种情况下是不可能的还是在这里怎么做?这是我的代码:

接口iobject:

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

【问题讨论】:

  • 注意什么错误?
  • [OT]:delete 丢失(甚至更好:存在额外的new:使用智能指针)。

标签: c++ interface virtual destructor


【解决方案1】:

您需要定义您声明的每个虚拟析构函数。假设您不希望析构函数执行超出默认行为的操作,则可以使用声明进行定义: 而不是:

virtual ~IObject();

使用

virtual ~IObject() {}

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

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

【讨论】:

  • 谢谢!你知道为什么我不能删除析构函数中的双打吗? c++ 这么说:不能删除'double'类型的表达式
  • delete 用于通过指针拥有的对象。赋予 delete 的表达式类型必须是指针。如果您使用new 分配了一个double,那么delete 将是正确的,并且您将使用指向该double 的指针的表达式来执行此操作,而不是使用double 本身的表达式。如果 double 是某个其他对象的一部分,或者是局部变量,或者不是直接用 new 分配的,那么 delete 它是不正确的。
【解决方案2】:

您需要在代码中定义虚拟析构函数。 正如您的错误中明确提到的那样。

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

注意:缺少 vtable 通常意味着第一个非内联虚拟成员 函数没有定义。

virtual ~IObject() {} 就足够了。

【讨论】:

    【解决方案3】:

    您的析构函数缺少定义。

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

    virtual ~X() = default;
    

    这比提供一个空的身体要好:

    virtual ~X() { }
    

    因为用户提供的1 析构函数阻止该类成为trivially destructible


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

    【讨论】:

      猜你喜欢
      • 2014-06-23
      • 2016-08-14
      • 2020-07-06
      • 2012-10-24
      • 2017-01-27
      • 1970-01-01
      • 2017-08-13
      • 2011-05-21
      • 2013-01-27
      相关资源
      最近更新 更多