Search code examples
c++inheritancemethodsmakefileoverriding

multiple definition of... + undefined reference to... the same function


my programm has various errors that i don't quite understand.

in geraet.cpp i want to override the method schalten() from elektronik.cpp, but after compiling each component i cant link them (g++ -o main main.o elektronik.o geraet.o) with these errors:

/usr/bin/ld: geraet.o: in function `schalten()':
geraet.cpp:(.text+0x0): multiple definition of `schalten()'; elektronik.o:elektronik.cpp:(.text+0x0): first defined here
/usr/bin/ld: main.o: in function `main':
main.cpp:(.text+0x23): undefined reference to `Geraet::schalten()'
collect2: error: ld returned 1 exit status

my intention for the first error was to make the method virtual in elektronik.h, but that makes the error even worse:

/usr/bin/ld: geraet.o: in function `schalten()':
geraet.cpp:(.text+0x0): multiple definition of `schalten()'; elektronik.o:elektronik.cpp:(.text+0x0): first defined here
/usr/bin/ld: main.o: warning: relocation against `_ZTV6Geraet' in read-only section `.text'
/usr/bin/ld: main.o: in function `main':
main.cpp:(.text+0x1e): undefined reference to `vtable for Geraet'
/usr/bin/ld: main.cpp:(.text+0x2e): undefined reference to `Geraet::schalten()'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE
collect2: error: ld returned 1 exit status

can someone please explain ...

...why i cant simply override the method in the child class?
...why i cant solve this problem with a virtual method?
...why the method is undefined when linking the objects?


Here my code:

main.cpp

#include "elektronik.h"
#include "geraet.h"
#include <iostream>

int main() {

    Geraet tool{};
    std::cout << tool.schalten() << std::endl;

    return 0;
}

elektronik.h

#pragma once

class Elektronik {
    public:
        bool schalten();
};

elektronik.cpp

#include "elektronik.h"

bool schalten() {
    return false;
}

geraet.h

#pragma once

class Geraet : public Elektronik {
    public:
        bool schalten();
};

geraet.cpp

#include "geraet.h"

bool schalten() {
    return true;
}

Solution

  • When you define a function in cpp, you need to use the whole (prefixed) name, e.g.:

    #include "elektronik.h"
    
    bool Elektronik::schalten() {
        return false;
    }
    

    Same for Geraet. This is because, without prefix, the compiler will consider it to be a free function (in the given namespace).