История изменений
Исправление zaz, (текущая версия) :
Потомучто так работает линковщик (и он обязан так работать). Например вы используете std::cout в one.cpp и в two.cpp, это приводит к тому что при компиляции вы получите бинарный код реализующий std::cout и в one.obj и в two.obj далее линковщик при линковке уберет лишние копии std::count и оставит только одну. Чтобы было более понятно поправим ваш пример:
Добавим новый файл impl.hpp:
struct Realization : Interface {
void run() {
r1();
}
static void r1() {
std::cout << R_ID << std::endl;
}
};
Поправим one.cpp:
#include "one.h"
#include "interface.h"
#include <iostream>
#define R_ID "r1"
#include "impl.hpp"
void OneRunner::run() {
Realization r;
r.run();
}
two.cpp:
#include "two.h"
#include "interface.h"
#include <iostream>
#define R_ID "r2"
#include "impl.hpp"
void TwoRunner::run() {
Realization r;
r.run();
}
Исходная версия zaz, :
Потомучто так работает линковщик (и он обязан так работать). Например вы используете std::cout в one.cpp и в two.cpp, это приводит к тому что при компиляции вы получите бинарный код реализующий std::cout и в one.obj и в two.obj далее линковщик при линковке уберет лишние копии std::count и оставит только одну. Чтобы было более понятно поправим ваш пример:
Добавим новый файл impl.hpp:
void run() {
r1();
}
static void r1() {
std::cout << R_ID << std::endl;
}
};
Поправим one.cpp:
#include "one.h"
#include "interface.h"
#include <iostream>
#define R_ID "r1"
#include "impl.hpp"
void OneRunner::run() {
Realization r;
r.run();
}
two.cpp:
#include "two.h"
#include "interface.h"
#include <iostream>
#define R_ID "r2"
#include "impl.hpp"
void TwoRunner::run() {
Realization r;
r.run();
}