Почему компоновщик ld допускает несколько определений классов с одними и теми же методами?

Рассмотрим этот файл, first.cpp, содержащий определение класса и использование:

#include <iostream>

struct Foo
{
    Foo(){ std::cout << "Foo()" << std::endl; }
    ~Foo(){ std::cout << "~Foo()" << std::endl; }
};

int main(){
    Foo f;
    return 0;
}

и другой, second. cpp, содержащий конфликтующее определение класса:

#include <iostream>

struct Foo
{
    Foo();
    ~Foo();
};

Foo::~Foo(){ std::cout << "wrong ~Foo()" << std::endl; }

Компоновщик жалуется на повторяющиеся символы, когда определены две функции с одинаковыми именами, но эти файлы с повторяющимися методами класса компилируются без ошибок.

Я скомпилировал с помощью следующих команд:

$ g++ -c second.cpp -o second
$ g++ second first.cpp -o first

Изменение порядка аргументов для второго вызова g++не меняет вывод.

И когда firstзапускается, вот что выводится:

$ ./first
Foo()
wrong ~Foo()

Почему компоновщик разрешает повторяющиеся методы класса?Если это явно разрешено, почему неправильно ~Foo() напечатано?

18
задан Rafał Rawicki 16 May 2016 в 09:52
поделиться