Задать вопрос
@4ainik
начинал с бейсика на 286 в 1994

В чем ошибка в исходном коде, и есть ли она?

Здравствуйте. Есть простой исходный код:
class TLibrary{
    HINSTANCE hModule;
    TLibrary( const TLibrary &){}
    TLibrary(){}
public:
    TLibrary(const char *LibName){
        if( ( hModule = LoadLibrary(LibName) ) == NULL )
            throw Exception("Can't load library");
    }
    virtual FARPROC getProcAddress(const char *ProcName){
        FARPROC ptr = GetProcAddress(hModule, ProcName);
        if( ptr == NULL )
            throw Exception("Can't find func");
        return ptr;
    }
    virtual ~TLibrary(){
        FreeLibrary(hModule);
    }
};


Думал, что он не содержит ошибок, и он действительно успешно компилируется без каких либо предупреждений и даже работает. Но вот простая проверка статическим анализатором кода выявила определенные потенциальные проблемы:
http://cppcheck.sourceforge.net/cgi-bin/democlient.cgi
Cppcheck 1.84

[test.cpp:3]: (warning, inconclusive) Member variable 'TLibrary::hModule' is not initialized in the constructor.
[test.cpp:6]: (style) Class 'TLibrary' has a constructor with 1 argument that is not explicit. Such constructors should in general be explicit for type safety reasons. Using the explicit keyword in the constructor means some mistakes when using the class can be avoided.
[test.cpp:1]: (warning) The class 'TLibrary' has 'copy constructor' but lack of 'operator='.
Done!


Есть ли здесь специалисты, которые могли бы объяснить на простом родном языке, в чем же тут проблема?
  • Вопрос задан
  • 679 просмотров
Подписаться 1 Сложный 9 комментариев
Решения вопроса 1
Я так понимаю, что это С++ (луше было бы именно его в тегах поставить).

Судя по коду, вы хотите просто спрятать пару конструкторов. Для этого достаточно объявить их в приватной части класса, но не обязательно определять. Исправьте на такое, и будет вам счастье:

TLibrary( const TLibrary &);
TLibrary();
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
vt4a2h
@vt4a2h Куратор тега C++
Senior software engineer (C++/Qt/boost)
[test.cpp:3]: (warning, inconclusive) Member variable 'TLibrary::hModule' is not initialized in the constructor.

В C++ всё (почти) необходимо явно инициализировать, а то потом можно получить очень интересные проблемы. В конструкторе необходимо инициализировать все поля класса в порядке объявления. Начиная с C++11 можно инициализировать по умолчанию через равно в момент объявления.

[test.cpp:6]: (style) Class 'TLibrary' has a constructor with 1 argument that is not explicit. Such constructors should in general be explicit for type safety reasons. Using the explicit keyword in the constructor means some mistakes when using the class can be avoided.

К конструкторам с одним аргументом лучше добавлять explicit, чтобы избежать неявных преобразований и всяких интересных эффектов по ходу работы программы.

(warning) The class 'TLibrary' has 'copy constructor' but lack of 'operator='.

Золотое правило: сами реализовали деструктор, конструктор копии, оператор копирования, конструктор перемещения или оператор перемещения, задумайтесь о том, что вам возможно надо реализовать все пять методов.
Ответ написан
BacCM
@BacCM
C++ почти с рождения
Зависит от того как этот класс будет использоваться. Но потенциально ошибки есть:
1. При копировании объекта класса, исходный объект и копия будут иметь одно и тоже значение hModule
И если двойное освобождение может и прокатит относительно безболезненно, то вызов функции для освобожденного хендла уже нет.
2. Исключение из конструктора. Тут ни к чему плохому не приведет, но потенциально при расширении функционала и как подход вообще - весьма плох
3. То что поле класса потенциально может быть непроинициализировано, тоже понятно.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы