C++ 父类中对方法的未定义引用

C++ 父类中对方法的未定义引用,c++,oop,undefined-reference,C++,Oop,Undefined Reference,我的课程有三节课 class A { public: virtual ~A() { decompose(); } virtual void decompose(); }; class B:public A { private: int *b_data; public: void decompose() { if (b_data != NULL) delete [] b_data; } }; class C:public A { private: i

我的课程有三节课

class A {
public:
  virtual ~A() {
    decompose();
  }
  virtual void decompose();
};

class B:public A {
private:
  int *b_data;
public:
  void decompose() {
    if (b_data != NULL) delete [] b_data;
  }
};

class C:public A {
private:
  int *c_data;

public:
  void decompose() {
    if (b_data != NULL) delete [] c_data;
  }
};
但是当我用g++编译这段代码时,我得到了一个错误:

In function `~A':
undefined reference to `vtable for A'
undefined reference to `A::decompose()'

In function `A':
undefined reference to `vtable for A'
undefined reference to `typeinfo for A'
undefined reference to `typeinfo for A'
如果有帮助的话,类A在.h文件中定义,它的析构函数是内联定义的,另外两个类有两个文件.h和.cpp

在我的程序中,我根据以下内容调用这些类:

int main() {
  A *a;
  a = new B();  //constructor is defined
  delete a;
  return 0;
}

这段代码有问题吗?

在构造函数和析构函数中调用虚函数时要小心。它们不会像正常情况那样被覆盖。A.~A总是调用A::分解。我认为编译器正在抱怨它找不到这个函数。

在构造函数和析构函数中调用虚函数时要小心。它们不会像正常情况那样被覆盖。A.~A总是调用A::分解。我认为编译器正在抱怨它找不到这个函数。

在基类中创建A::decompose函数的实现

virtual void decompose(){};

在基类中创建A::decompose函数的实现

virtual void decompose(){};

该错误是由于在B和C析构函数中调用a::decompose引起的。即使析构函数是虚拟的,并且方法本身也是虚拟的,也会调用A::decompose。当为派生对象B或C运行析构函数时,该对象的派生部分已被销毁

class A {
public:
  virtual void decompose() { std::cout << "A";}
  virtual ~A() {
    decompose();
  }
};

class B:public A {
private:
  int *b_data;
public:
  void decompose() {
      std::cout << "B";
    if (b_data != NULL) delete [] b_data;
  }
};

class C:public A {
private:
  int *c_data;
public:
  void decompose() {
      std::cout << "C";
    if (c_data != NULL) delete [] c_data;
  }
  ~C() {}
};

int main(int argc, char** argv) {
    B b;
    C c;
    return 0;
}
输出:

AA

解决方案:
该错误是由于在B和C析构函数中调用a::decompose引起的。即使析构函数是虚拟的,并且方法本身也是虚拟的,也会调用A::decompose。当为派生对象B或C运行析构函数时,该对象的派生部分已被销毁

class A {
public:
  virtual void decompose() { std::cout << "A";}
  virtual ~A() {
    decompose();
  }
};

class B:public A {
private:
  int *b_data;
public:
  void decompose() {
      std::cout << "B";
    if (b_data != NULL) delete [] b_data;
  }
};

class C:public A {
private:
  int *c_data;
public:
  void decompose() {
      std::cout << "C";
    if (c_data != NULL) delete [] c_data;
  }
  ~C() {}
};

int main(int argc, char** argv) {
    B b;
    C c;
    return 0;
}
输出:

AA

解决方案:

你是用g++编译的吗?我是用g++和@lizusek我编辑了问题A::decompose没有定义,你打算让它成为纯虚拟功能吗?搜索纯虚拟功能functions@K-ballo那不行,因为他在析构函数中调用它。你用g++编译吗?我用的是g++和@lizusek我编辑了问题A::decompose没有定义,你打算让它成为纯虚拟功能吗?搜索纯虚拟功能functions@K-ballo这不起作用,因为他在析构函数中调用它。如果它是空的,那么定义它有什么意义?我用它来清理我的内存和删除数据结构。它也会调用子级分解吗?@emab编译器不知道它是空的,直到你提供一个定义说它是空的。没有语言规则说如果函数没有实现,那么它默认为空。那么我应该如何调用儿童析构函数呢?创建此分解的要点是将其用作子级的析构函数。@emab您必须实际向B和C添加析构函数,并从每个子级调用分解。如果它为空,那么定义它的意义是什么?我用它来清理我的内存和删除数据结构。它也会调用子级分解吗?@emab编译器不知道它是空的,直到你提供一个定义说它是空的。没有语言规则说如果函数没有实现,那么它默认为空。那么我应该如何调用儿童析构函数呢?创建此分解的要点是将其用作子级的析构函数。@emab您必须实际向B和C添加一个析构函数,并从每个子级调用decompose。但是如何调用B和C的析构函数呢?@emab它们被调用。问题是,在~A中调用decompose无法正常工作。它只是C++的一个规则。你必须解决这个问题。我不能使用B和C的直接声明,否则就没有问题了,它们的析构函数会被立即调用。@NeilKirk我明白你的意思,有没有办法调用儿童的析构函数?在我的生活中,他们没有被召唤example@emab正确的析构函数是通过虚拟分派调用的,请参见我在回答中给出的答案,但是我如何调用B和C的析构函数?@emab它们被调用。问题是,在~A中调用decompose无法正常工作。它只是C++的一个规则。你必须解决这个问题。我不能使用B和C的直接声明,否则就没有问题了,它们的析构函数会被立即调用。@NeilKirk我明白你的意思,有没有办法调用儿童的析构函数?在我的生活中,他们没有被召唤example@emab通过虚拟分派调用适当的析构函数,请参见答案中给出的my。当从构造函数或析构函数直接或间接调用虚拟函数时,包括在类的非静态数据成员的构造或销毁过程中,这方面的标准文本为[class.cdtor]4,调用所应用的对象是在构造或销毁中调用它的对象x,调用的函数是构造函数或析构函数类中的最终重写器,而不是在更派生的类中重写它的函数。这方面的标准文本是[class.cdtor]4当从构造函数或析构函数直接或间接调用虚函数时,包括在类的非sta的构造或销毁期间 tic数据成员,并且调用应用的对象是正在构造或销毁的对象call it x,调用的函数是构造函数或析构函数类中的最终重写器,而不是在更派生的类中重写它的函数。