LINUX.ORG.RU

История изменений

Исправление 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();
}