Я использовал для определения определений своих виртуальных деструкторов встроенный для облегчения, хотя он не упал. Сегодня я решил сделать небольшой тест, чтобы понять, что происходит.Почему это не обеспечивает множественную ошибку определения?
dummy.h
#ifndef DUMMY_HEADER
#define DUMMY_HEADER
#include <iostream>
class Dummy
{
public:
virtual ~Dummy() {std::cout << "dummy destroyed" << std::endl;}
};
class DummyEx : public Dummy
{
public:
virtual ~DummyEx() {std::cout << "DummyEx destroyed" << std::endl;}
};
#endif
deleter.cpp
#include "dummy.h"
void deleteDummy(Dummy* dummy)
{
delete dummy;
}
main.cpp
#include "dummy.h"
void deleteDummy(Dummy* dummy);
int main()
{
Dummy* dummy = new DummyEx();
delete dummy;
dummy = new DummyEx();
deleteDummy(dummy);
return 0;
}
Я составил deleter.cpp
с g++ -c deleter.cpp
и я получил deleter.o
Я составил main.cpp
с g++ -c main.cpp
и я получил main.o
Я связала объектные файлы с g++ deleter.o main.o
и я получил a.out
Когда я исполняю a.out
, выход был, как и ожидалось, оба couts из Dummy
и DummyEx
деструкторов были там.
Но к какому объектовому файлу идет скомпилированное определение деструкторов? Они не могли попасть в оба объектных файла, так как при связывании я не получал множественную ошибку определения. Кроме того, компилятор не включил деструкторы, так как виртуальные функции были правильно вызваны.
Правило с одним определением не применяется к встроенным функциям. Ваши деструкторы неявно встроены. Спецификация языка говорит, что это должно работать. Вы спрашиваете, как это делает компилятор/компоновщик? – juanchopanza
ODR применяется к встроенным функциям, но он указывает, что они должны иметь точно такое же определение, если существует несколько определений –