Lista kontrolna do pisania konstruktora kopiującego i operatora przypisania w C++

Proszę napisać listę zadań, które Konstruktor kopiujący i operator przypisania muszą wykonać w C++, aby zachować bezpieczeństwo WYJĄTKÓW, uniknąć wycieków pamięci itp.

Author: Daniel Daranas, 2008-10-18

4 answers

Najpierw upewnij się, że naprawdę potrzebujesz wsparcia copy. W większości przypadków tak nie jest, a zatem wyłączenie obu jest drogą do zrobienia.

Czasami nadal będziesz musiał dostarczyć duplikację na klasie z hierarchii polimorficznej, w takim przypadku: wyłącz operator przypisania, napisz (protected?) Konstruktor kopiujący, oraz udostępnia funkcję virtual clone ().

W Przeciwnym Razie, w przypadku, gdy piszesz klasę wartości, wracasz do krainy ortogonalnej kanonicznej formy Coplien. Jeśli masz element, którego nie można skopiować trywialnie, musisz podać Konstruktor kopiujący, Destruktor, operator przypisania i konstruktor domyślny. Zasada ta może być udoskonalona, zobacz na przykład: prawo Wielkiej dwójki

Polecam również zajrzeć do C++ FAQ odnośnie operatorów przydziałów, oraz do idiomu copy-and-swap i do GOTW .

 15
Author: Luc Hermitte,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-15 20:26:37

Wersje generowane przez kompilator działają w większości sytuacji.

Musisz pomyśleć o problemie, gdy obiekt zawiera surowy wskaźnik (argument za brakiem surowych wskaźników). Więc masz surowy wskaźnik, drugie pytanie brzmi, czy jesteś właścicielem wskaźnika (czy jest on usuwany przez Ciebie)? Jeśli tak, to będziesz musiał zastosować zasadę 4.

Posiadanie więcej niż 1 surowego wskaźnika staje się coraz trudniejsze do poprawnego wykonania (wzrost złożoności nie jest również liniowy [ale to jest obserwacyjne i nie mam prawdziwych statystyk na poparcie tego stwierdzenia]). Więc jeśli masz więcej niż 1 surowy wskaźnik pomyśl o owinięciu każdego z nich we własnej klasie (jakaś forma inteligentnego wskaźnika).

Reguła 4: jeśli obiekt jest właścicielem surowego wskaźnika, musisz zdefiniować następujące 4 członków, aby upewnić się, że poprawnie obsługujesz zarządzanie pamięcią:

  • Konstruktor
  • Konstruktor Kopiujący
  • Operator Przypisania
  • Destructor

Jak ty zdefiniuj te będą zależeć od sytuacji. Ale na co uważać:

  • domyślna konstrukcja: ustaw wskaźnik NA NULL
  • Konstruktor kopii: użyj Copy and Swap ideum, aby zapewnić "silną gwarancję WYJĄTKÓW"
  • operator przypisania: Sprawdź przypisanie do siebie
  • Destruktor: Ochrona przed wyjątkami rozprzestrzeniającymi się z destruktora.
 4
Author: Martin York,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-24 11:59:07

Spróbuj to przeczytać.

Http://www.icu-project.org/docs/papers/cpp_report/the_anatomy_of_the_assignment_operator.html

Jest bardzo dobrą analizą operatora przypisania

 1
Author: ugasoft,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-06 15:56:20

Nie mam pojęcia o wyjątkach tutaj, ale idę tędy. Wyobraźmy sobie, że jest to szablon wrapper tablicy. Mam nadzieję, że to pomoże:)

Array(const Array& rhs)
    {
        mData = NULL;
        mSize = rhs.size();
        *this = rhs;
    }

    Array& operator=(const Array& rhs)
    {
        if(this == &rhs)
        {
            return *this;
        }

        int len = rhs.size();

        delete[] mData;

        mData = new T[len];

        for(int i = 0; i < len; ++i)
        {
            mData[i] = rhs[i];
        }

        mSize = len;

        return *this;
    }
 -2
Author: Nazgob,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-18 11:30:04