Различные реализации линкеров и динамических линкеров обеспечат нечто похожее на решение этой проблемы, как уже упоминали другие.
Однако, если вы переопределяете одну функцию C ++, используя любую из этих функций (GNU ld's --wrap, ld.so's LD_PRELOAD и т. Д.), вы нарушаете правило одного определения и, таким образом, вызываете неопределенное поведение.
Во время компиляции вашей библиотеки компилятору разрешено включать данную функцию любым способом, который он сочтет нужным, что означает, что ваше переопределение функции может быть вызвано не во всех случаях.
Рассмотрим следующий код:
class A
{
public:
void foo();
void bar();
};
void A::foo()
{
std::cout << "Old version.\n";
}
void A::bar()
{
foo();
}
GCC 4.5, когда вызывается с -O3, фактически решит встроить определение foo () в bar (). Если вы каким-то образом заставили свой компоновщик заменить это определение A :: foo () на ваше собственное определение, A :: bar () все еще выведет строку "Старая версия. \ N".
Итак, одним словом: не надо.