2013-06-09 2 views
0

Я создал общую библиотеку, которую я использую в другом приложении. Одной из основных функций общей библиотеки является базовый класс, который проверяет наличие утечек.Чистые виртуальные функции в общедоступном API для общей библиотеки (C++)

Код в библиотеке выглядит следующим образом:

// LeakCheck.hpp 
#include <vector> 
class LeakCheck 
{ 
private: 
    static std::vector<LeakCheck*> objects; 
public: 
    virtual const char *getClassName() const = 0; 
    LeakCheck(); 
    ~LeakCheck(); 
    friend class LeakCheckMaster; 
}; 

// LeakCheck.cpp 
#include <iostream> 
class LeakCheckMaster 
{ 
    ~LeakCheckMaster() 
    { 
     if (LeakCheck::objects.size()>0) { 
      std::cerr << "Leaked objects:" << std::endl; 
      for (int i=0; i<LeakCheck::objects.size(); i++) 
       std::cerr << LeakCheck::objects[i]->getClassName() << std::endl; 
     } 
    } 
} master; 
std::vector<LeakCheck*> LeakCheck::objects; 
LeakCheck::LeakCheck() 
{ 
    objects->push_back(this); 
} 
LeakCheck::~LeakCheck() 
{ 
    objects->remove(this); 
} 

тестовое приложение будет:

#include "LeakCheck.hpp" 


class Test : public LeakCheck 
{ 
    public: 
     const char *getClassName() const 
     { 
      return "Test"; 
     } 
}; 

int main() 
{ 
    Test *a = new Test(); 
    return 0 
} 

Однако, когда я пытаюсь связать приложение, я получаю «неопределенная ссылка на LeakCheck: : GetClassName()». Я уверен, что у меня есть ссылка с разделяемой библиотекой, потому что работают другие функции.

Это не код активации. Я попытался оставить только код, необходимый для этой проблемы. Надеюсь, я ничего не пропустил.

Итак, почему возникает эта ошибка компоновщика? Если я изменю его с чистого виртуального, чтобы вернуть «неназванный класс». Результат выводит все объекты как «неназванный класс», хотя я реализовал функцию getClassName().

Невозможно ли абстрагироваться через границы разделяемой библиотеки?

+0

Эта последняя функция LeakCheck.hpp должна быть dtor, верно? – idoby

+0

Кстати, вы используете два статически инициализированных объекта (LeakCheck :: objects и LeakChecker), а один из них использует другой, но порядок их инициализации/финализации может отличаться от желаемого. – Inspired

+0

Знаешь что? Ты прав. Это небезопасно. Хорошо, вернемся к чертежной доске .. спасибо в любом случае! – bofjas

ответ

1

Абстрактный метод должен быть также виртуальным: virtual const char *getClassName() const = 0;

+0

извините .. это был просто недосмотр, когда я скопировал код, но спасибо, что указали его. Исправлено. (Это не было причиной проблемы) – bofjas

+0

Действительно ли это 'virtual' в вашем действительном коде? Все эти сообщения об ошибках и поведение при его реализации в базовом классе выглядят как не виртуальный метод. – Inspired

+0

есть. он находится в фактическом коде. Думаю, я должен был попытаться скомпилировать его перед публикацией. Извини за это. Можно ли даже разрешить определение не виртуальной функции равным 0? – bofjas

Смежные вопросы