Вопрос по pointers, compiler-warnings, rule-of-three, c++, g++ – Понимание -Weffc ++

11

Рассмотрим следующую программу:

#include <string>

struct S {
    S (){}

private:
    void *ptr = nullptr;
    std::string str = "";
};

int main(){}

Это, когда скомпилировано с-Weffc++ на GCC 4.7.1 выложу:

warning: 'struct S' has pointer data members [-Weffc++]
warning:   but does not override 'S(const S&)' [-Weffc++]
warning:   or 'operator=(const S&)' [-Weffc++]

Обычно это не проблема, за исключением пары вещей в этом примере:

If I comment out any of the constructor, the pointer declaration, or the string declaration, the warning disappears. This is odd because you'd think the pointer alone would be enough, but it isn't. Furthermore, changing the string declaration to an integer declaration causes it to disappear as well, so it only comes up when there's a string (or probably other choice classes) with it. Why does the warning disappear under these circumstances?

Often times this warning comes up when all the pointer is doing is pointing to an existing variable (most often maintained by the OS). There's no new, and no delete. When the class with the handle, in these cases, is copied, I don't want a deep copy. I want both handles to point to the same internal object (like a window, for example). Is there any way to make the compiler realize this without unnecessarily overloading the copy constructor and assignment operator, or disabling the warning completely with #pragma? Why am I being bothered in the first place when the Rule of Three doesn't even apply?

Ваш Ответ

2   ответа
20

-Weffc++ есть несколько проблем, я никогда не использую его. Код, который проверяет наличие «проблем» является довольно упрощенным, и поэтому предупреждения оказываются слишком грубыми и бесполезными.

Это конкретное предупреждение основано на пункте 11 первого изданияEffective C++ и Скотт изменил это (к лучшему) в более поздних выпусках. Код G ++ не проверяет фактическое динамическое размещение, только наличие членов-указателей.

Посмотрите, что я написал об этом предупреждении вБагзилла GCC при сравнении руководящих принципов в первом издании с третьим изданием:

Item 11: Define a copy constructor and an assignment operator for classes with dynamically allocated memory.

Replaced by Item 14: "Think carefully about copying behavior in resource-managing classes" - the advice is less specific, but more useful. I'm not sure how to turn it into a warning though!

Еще одна проблема с -Weffc ++: наличие не виртуального деструктора наprivate Базовый класс не допускается без уважительной причины.
5

you have a POD structure. As it cannot have any constructors, -Weffc++ doesn't bother checking.

Use a reference or shared_ptr object or any other object that wrap a pointer.

Да, большая часть винапи - это C. Проблема заключается в том, что вы оборачиваете их в классах, но, поскольку они являются технически указателями, предупреждение появляется без приглашения. chris
Да, похоже, HWND не предназначен для C ++. В любом случае, это хорошая идея - обернуть старые структуры C в некоторые классы, чтобы сделать C ++ более эффективным. Подсказка в том, что класс играет роль в концептуальном моделировании.
Не знаю, чтоHWND но если это указатель и у вас естьCreateWindowВам, вероятно, придется позвонитьDestroyWindow ос что-то. Тогда это хорошее место для shared_ptr & lt; HWND & gt; сDestroyWindow привязан к деструктору, это не так,-Weffect  не для тебя.
Я вроде думал, что это может быть что-то подобное для # 1. Но для № 2 я никогда не видел и не представлял себе их использование для ручек, используемых для взаимодействия с системой. Все, что вы делаете, это передвигаете указатель; вы можете обращаться с ним так, как будто он вообще не является указателем, поскольку все, что важно, - это адрес, на который он указывает, а не то, что там находится. Ручка окна техническиvoid *, Использование идет что-то вродеHWND hwnd = CreateWindow (...); ShowWindow (hwnd, SW_SHOW); Каждый аспект указателя уже позаботился; это вроде как уже умный указатель. Что вы делаете в этом случае? chris
Да, это один из множества объектов, хранящихся в видеvoid *, Самое смешное в этомDestroyWindow обычно чтоmakes ручка окна выходит из области видимости. Другие могут не требовать, чтобы вы вызывали что-то, чтобы удалить их. Вещь оshared_ptr<HWND> что это какHWND *, который не нужен. Это должно быть больше похоже наshared_ptr<void>, но ручки - это не то, что вы разыскиваете или что-то в этом роде. В этом случае указатели можно рассматривать как нормальные переменные. chris

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