未将方法声明为纯虚函数为何引发Qt MOC的vtable未定义错误?
Let’s unpack this step by step—this error might feel tied to Qt’s MOC tool at first glance, but it’s actually a core C++ virtual table (vtable) issue that just popped up in your Qt Creator project.
First, a quick refresher on vtables: C++ uses vtables to handle virtual function calls. Any class with at least one virtual function gets a vtable—a table of pointers pointing to the actual implementations of those virtual functions.
Your Graph class has a virtual destructor (great practice!) and a topologicalSort method marked virtual, but you didn’t make it pure virtual (missing the = 0). Here’s the problem: when you declare a virtual function that’s not pure, the compiler expects you to provide a default implementation for it—either right in the class body or in a matching .cpp file. If you skip this, the compiler can’t generate a complete vtable for Graph because there’s no valid pointer to an implementation of topologicalSort to put in that table.
The error message points to your Graph constructor and destructor not because those functions are broken, but because those are the spots where the compiler sets up the vtable pointer for each instance of the class. When it tries to do that, it realizes the vtable is incomplete, so it throws that "undefined reference" error.
You mentioned looking into MOC files, and that’s a reasonable gut reaction—Qt’s MOC can cause vtable-related errors (like if you forget to run it on a class with Q_OBJECT). But in this case, your Graph class doesn’t use any Qt-specific macros, so MOC isn’t involved here. The confusion likely comes from the fact that vtable errors in Qt projects often get linked to MOC, but this is a plain old C++ issue.
To fix this, you’ve got two clear options:
- Make
topologicalSortpure virtual: Add= 0to the declaration, like this:
This tells the compiler that[[nodiscard]] virtual std::vector<int> topologicalSort() const = 0;Graphis an interface—derived classes likeMGraphmust provide their own implementation, andGraphitself doesn’t need a default one. This is the right move here since you’re usingGraphas a base interface. - Provide a default implementation: If there’s a sensible default behavior for
topologicalSortin the base class, you can write that in theGraphclass body or a.cppfile. But sinceGraphis meant to be an interface, this is probably not what you want.
As you found by comparing to your working old project, marking the function pure virtual resolves the error because it completes the vtable setup for the Graph class.
内容的提问来源于stack exchange,提问作者Sazonov Nikita

