【问题标题】:How to make this destructor virtual如何使这个析构函数成为虚拟的
【发布时间】:2015-10-02 01:49:22
【问题描述】:
#include "RegionsSingleImage.hpp"

#include <iostream>
#include <vector>

using std::vector;
using std::cerr;
using std::cout;
using std::endl;

RegionsSingleImage::RegionsSingleImage(std::string fName){
#ifdef __CVLOADIMAGE_WORKING__
  im = cvLoadImage(fName.c_str(), CV_LOAD_IMAGE_COLOR);
#else
  im = readImage(fName.c_str(), CV_LOAD_IMAGE_COLOR);
#endif
  if(im == NULL)
  {
    cerr << "Could not read image from " << fName << endl;
    assert(false);
  }
  list = new std::vector<Region *>;
}

RegionsSingleImage::RegionsSingleImage(IplImage *I)
{
  assert(I != NULL);
  im = cvCreateImage(cvGetSize(I), I->depth, I->nChannels);
  cvCopy(I, im, 0);
  list = new std::vector<Region *>;
}

RegionsSingleImage::~RegionsSingleImage()
{
  if(list)
    for(unsigned int i=0; i< list->size(); i++)
      if(list->at(i))
    delete(list->at(i)); 
  delete(list);
  cvReleaseImage(&im);
}

我需要将我的析构函数设为虚拟,因为它处理抽象对象,但是我不确定我可以在哪里放置“虚拟”关键字或如何根据布局组织代码。感谢您的帮助!

【问题讨论】:

  • virtual 关键字需要放在 declaration(通常在 .hpp 文件中),而不是 定义(通常在 .hpp 文件中)。 cpp 文件,内联或模板函数除外)

标签: c++ virtual abstract overloading


【解决方案1】:

你只需要声明为virtual,例如

class RegionSingleImage {
  ..
  virtual ~RegionSingleImage();
}

请注意,这必须在要为其存储指针的层次结构的第一个对象上完成,并且只针对它,因为它在任何子类中都是隐式虚拟的(就像每个 virtual 方法一样)。

【讨论】:

    【解决方案2】:

    您将virtual 关键字放在标题声明"RegionsSingleImage.hpp" 中。

    【讨论】:

    • "你也可以在.cpp文件中用virtual来标记定义", no
    • @Cheersandhth.-Alf 是的,我大错特错,我实际上是在考虑派生类中的声明。谢谢,已删除。
    • 啊,谢谢。这样做会阻止从另一个文件调用析构函数的警告,但是,我仍然收到错误:RegionsSingleImage.cpp:38:5: warning: delete called on 'Region' that is abstract but has non-virtual destructor [-Wdelete-non-virtual-dtor] 删除(list->at(i))
    • 知道可能是什么原因吗?谢谢!
    • @DannyFitzpatrick 如果Region 是一个抽象类,因此它具有(纯)虚函数,请确保它具有虚析构函数,就像virtual ~Region() = default; 一样简单。否则,当您尝试通过指向 Region 的指针删除派生对象时会遇到麻烦(实际上,您有未定义的行为,这是最糟糕的事情之一)。作为一般规则,每个包含虚函数并且可以通过指针在层次结构中使用的类都需要有一个虚析构函数。
    猜你喜欢
    • 2011-05-20
    • 2022-01-01
    • 2010-11-10
    相关资源
    最近更新 更多