Понимание -WeffC++

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

#include <string>

struct S {
    S (){}

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

int main(){}

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

предупреждение: 'struct S' имеет члены-указатели данных [-WeffC++]
предупреждение: но не переопределяет 'S(const S&)' [-WeffC++]
предупреждение: или 'operator=(const S&)' [-WeffC++]

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

  1. Если я закомментирую какой-либо конструктор, объявление указателя или объявление строки, предупреждение исчезнет. Это странно, потому что вы думаете, что одного указателя будет достаточно, но это не так. Кроме того, изменение строкового объявления на целочисленное объявление также приводит к его исчезновению, поэтому оно появляется только тогда, когда есть строка (или, возможно, другие классы выбора) с ней. Почему предупреждение исчезает при этих обстоятельствах?

  2. Часто это предупреждение появляется, когда все, что делает указатель, указывает на существующую переменную (чаще всего поддерживается ОС). Нет никаких new, и нет delete, Когда класс с дескриптором в этих случаях копируется, я не хочу глубокого копирования. Я хочу, чтобы обе ручки указывали на один и тот же внутренний объект (например, окно). Есть ли способ заставить компилятор понять это без излишней перегрузки конструктора копирования и оператора присваивания или полного отключения предупреждения с помощью #pragma? Почему меня беспокоит, во-первых, когда правило трех даже не применяется?

3 ответа

Решение
  1. Когда вы делаете это, у вас есть структура POD. Поскольку у него не может быть никаких конструкторов, -Weffc++ не надо проверять

  2. Используйте ссылку или shared_ptr объект или любой другой объект, который обернуть указатель.

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

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

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

Элемент 11: Определите конструктор копирования и оператор присваивания для классов с динамически выделяемой памятью.

Заменено пунктом 14: "Тщательно продумайте поведение копирования в классах управления ресурсами" - этот совет менее конкретен, но более полезен. Я не уверен, как превратить это в предупреждение, хотя!

Старый вопрос, но «обычно это не проблема» не совсем верно:

-Weffc++ заставляет ваш код отражать поведение. Здесь говорится о том, что если вы используете код как есть, неявный оператор копирования просто сделает точку «ptr» по тому же адресу, что и исходная структура.

ВОЗМОЖНО, ПОЭТОМУ ВЫ ХОТИТЕ, но это просто предупреждает вас, потому что это неявное поведение. Это может быть ясно для вас, когда вы пишете код, но будет ли это ясно для другого разработчика?

Что вам нужно сделать, чтобы избавиться от этого предупреждения, так это либо явно удалить оператор копирования и =, либо определить их. Чтобы удалить конструктор копирования, вы можете сделать следующее:

      S(const S&) = delete;
Другие вопросы по тегам