抽象基类GetName方法复用问题及LNK2019链接错误排查
Fixing the LNK2019 Linker Error
The LNK2019 error you're hitting comes from a missing definition for the pure virtual destructor in AbstractClass. Even though you declared it as virtual ~AbstractClass() = 0;, C++ requires all destructors (including pure virtual ones) to have a definition. This is because when you destroy a derived class object, the base class destructor is always invoked as part of the destruction chain.
To fix this, add a definition for the pure virtual destructor outside the class declaration:
#include <string> class AbstractClass { public: virtual ~AbstractClass() = 0; // Pure virtual destructor declaration std::string GetName() const { return m_Name; } private: std::string m_Name; }; // Definition for the pure virtual destructor AbstractClass::~AbstractClass() {}
Avoiding Overriding GetName() in Every Derived Class
Your current setup doesn't work because the base class's m_Name is private, so derived classes can't modify it. The m_Name in DerivedClass1 is a separate member variable entirely, and the base's GetName() has no access to it.
To avoid overriding GetName() in each derived class, you need a way for derived classes to initialize the base's m_Name without breaking encapsulation. The cleanest approach is to add a protected constructor to AbstractClass that accepts a name string, then have each derived class call this constructor with its specific name.
Here's the revised, working code:
Updated AbstractClass
#include <string> class AbstractClass { public: virtual ~AbstractClass() = 0; std::string GetName() const { return m_Name; } protected: // Protected constructor: only derived classes can call this explicit AbstractClass(std::string name) : m_Name(std::move(name)) {} private: std::string m_Name; }; AbstractClass::~AbstractClass() {}
Example Derived Class
class DerivedClass1 : public AbstractClass { public: // Pass our specific name to the base class constructor DerivedClass1() : AbstractClass("DerivedClass1") {} ~DerivedClass1() = default; };
Main Function (Unchanged)
#include <iostream> int main() { DerivedClass1 class1; std::cout << class1.GetName(); // Outputs "DerivedClass1" return 0; }
This approach has several benefits:
GetName()stays in the base class and never needs to be overridden- Each derived class only needs to specify its name once in the constructor
- Encapsulation is maintained (the base's
m_Nameremains private)
内容的提问来源于stack exchange,提问作者user7972945

