Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Undefined Reference to vtable After Adding Destructor

I looked at Undefined reference to vtable, but even after adding a destructor I am still met with a similar error:

main.cpp:(.text._ZN8isStringC2Ev[_ZN8isStringC5Ev]+0xf): undefined reference to `vtable for isString'
/usr/bin/ld: /tmp/ccVCX8sf.o: in function `isString::~isString()':
main.cpp:(.text._ZN8isStringD2Ev[_ZN8isStringD5Ev]+0xf): undefined reference to `vtable for isString'
/usr/bin/ld: /tmp/ccVCX8sf.o:(.data.rel.ro._ZTI8MyString[_ZTI8MyString]+0x10): undefined reference to `typeinfo for isString'
/usr/bin/ld: /tmp/ccVCX8sf.o:(.data.rel.ro._ZTI14CStringAdapter[_ZTI14CStringAdapter]+0x10): undefined reference to `typeinfo for isString'
collect2: error: ld returned 1 exit status

The following code is creating my own String class, but using an adapter for cstrings. They (MyString and CStringAdapter classes) inherit from a pure virtual class isString. I’m just trying to understand how to use adapters; I know creating my own string class is quite pointless.
I’m using C++ 17.

#include <iostream>
#include <cstring>

using namespace std;

class isString{
public:
    virtual ~isString()=default;
    virtual const char* getBuffer()const;
    virtual size_t size()const;
};

class CStringAdapter: public isString{
protected:
    string str;
public:
    CStringAdapter(): str{""} {}
    CStringAdapter(const char* newStr): str{newStr} {}
    ~CStringAdapter()=default;
    
    const char* getBuffer() const override { return str.c_str(); }
    size_t size() const override { return str.size(); }
};

class MyString: public isString{
protected:
    string str;
public:
    MyString():str{""} {}
    MyString(const char* newCStr) { *this = newCStr; }
    MyString(const MyString& newStr) { *this = newStr; }
    ~MyString()=default;
    
    MyString& Assign(const isString& myStr, const isString& aStr){
        memcpy(const_cast<char*>(myStr.getBuffer()), aStr.getBuffer(), aStr.size());
        return *this;
    }
    MyString& operator=(const MyString& aString){ return Assign(*this, aString); }
    MyString& operator=(const char* aCString){ return Assign(*this, CStringAdapter(aCString)); }

    const char* getBuffer() const override { return str.c_str(); }
    size_t size() const override { return str.size(); }
};

int main()
{
    MyString str1{"Hello World"};
    return 0;
}

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

You didn’t define the member functions isString::getBuffer and isString::size. You need to define them.

If you don’t want the class to have definitions for these functions, you must mark them as pure virtual, making isString an abstract base class which cannot be instantiated directly:

virtual const char* getBuffer() const = 0;
virtual size_t size() const = 0;
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading