У меня есть класс со статическим методом, который выглядит примерно так:
class X {
static float getFloat(MyBase& obj) {
return obj.value(); // MyBase::value() is virtual
}
};
Я вызываю его с экземпляром MyDerived, который подклассы MyBase:
MyDerived d;
float f = X::getFloat(d);
Если я свяжу файл obj, содержащий X, с моим исполняемым файлом, все будет работать как положено. Если я ожидаю получить 3.14, я получу его.
Если я создаю .lib, который содержит файл X.obj и ссылку в .lib, он ломается. Когда я вызываю getFloat (), он возвращает -1. # IND00 . Это какой-то тип дозорного значения, который должен сказать мне, что здесь не так?
Что-то отличается, когда вы ссылаетесь в lib, а не в obj напрямую?
Я не получаю никаких предупреждений или ошибок компилятора.
Edit:
Я использую Visual Studio 2005 на Windows XP Pro SP3. Чтобы убедиться, что я не связывал старые файлы, я клонировал метод value () в новый метод value2 () и вызвал его вместо этого. Поведение было таким же.
Редактировать # 2:
Итак, если я отследил вызов с помощью моего отладчика, я обнаружил, что он вообще не входит в мой метод value (). Вместо этого это входит в другой (не связанный) метод. Это заставляет меня думать, что мой vtable поврежден. Я думаю, что поведение, которое я вижу, должно быть побочным эффектом какой-то другой проблемы.
Решено! (спасибо Владу)
Оказывается, я нарушал одно определение правила (ODR), хотя это не было видно из кода, который я разместил. Эта - отличная статья парней из Visual C ++, которая объясняет проблему и один из способов ее устранения. Флаг компилятора / d1reportSingleClassLayout является фантастическим инструментом обучения.
Когда я выбросил макет моего класса для MyBase и MyDerived в двух разных проектах, я обнаружил различия между кодом вызова и кодом библиотеки. Оказывается, у меня в заголовочных файлах было несколько блоков # ifdef , а соответствующий оператор # define был в предварительно скомпилированном заголовке для основного проекта, но не в подпроекте (библиотеке). Я уже упоминал, насколько злыми я считаю макросы препроцессора?
В любом случае, я только публикую этот материал, потому что он может быть полезен кому-то еще. Этот вопрос также был очень полезен для меня.