Domyślne wartości członków najlepsza praktyka

Czy dobrą praktyką podczas pisania kodu C++11 jest ustawianie domyślnych wartości dla członków klasy w pliku nagłówkowym klasy?

Czy lepiej to zrobić w konstruktorze klasy?

EDIT:

Znaczy:

Foo.h :

#include <string>

using std::string;

class Foo{
    private:
        string greet = "hello";
    public:
        Foo();
};

VS

Foo.cpp (oczywiście z niezbędnym plikiem nagłówkowym, ale bez inicjalizacji w klasie):

Foo::Foo(){
    greet = "hello";
}
Która jest lepsza i dlaczego?
Author: Paul, 2012-07-21

3 answers

Jeśli członek klasy jest zawsze inicjowany tą samą wartością początkową, to powinieneś wprowadzić inicjalizator w linii, aby uniknąć powielania. Jeśli wartość początkowa zależy od konstruktora, umieść ją na liście inicjalizatorów konstruktora. (I nigdy nie używaj przydziału w sposób, w jaki to zrobiłeś.)

Przykład:

class Foo
{
    bool done = false;   // always start like this
    int qty;
    Bar * p;

public:
    Foo()                        : qty(0),              p(nullptr)    { }
    Foo(int q, Bar * bp)         : qty(q),              p(bp)         { }
    explicit Foo(char const * s) : qty(std::strlen(s)), p(new Bar(s)) { }

    // ...
};

W tym hipotetycznym przykładzie element done zawsze musi zaczynać się jako false, więc najlepiej jest napisać inicjator w linii. Pozostałych dwóch członków, qty i p, mogą być inicjowane w różny sposób w każdym z trzech różnych konstruktorów, więc są inicjowane wewnątrz list inicjujących konstruktorów.

ciekawostka: zauważ, że podanie inline initializer uniemożliwia twojej klasie posiadanie trywialnego konstruktora domyślnego.

 67
Author: Kerrek SB,
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
2012-07-21 19:13:59

To zależy czy trzeba pozostać kompatybilnym ze starszymi kompilatorami C++.Jeśli nie używasz C++11, musisz zainicjalizować większość członków (wszystkie niestatyczne) w konstruktorze. Ponadto wiele osób opowiada się za jawną inicjalizacją każdego członka, nawet jeśli oznacza to jawne wywołanie domyślnego ctor. Zazwyczaj należy umieścić szczegóły implementacji w pliku cpp, a nie w pliku nagłówkowym, stąd przykładem może być

Example:
//foo.h

class Foo{
public: 
  Foo();
private:
  std::vector<int> vect;
};

//foo.cpp

Foo::Foo():vect(){
}

W C++11 masz więcej opcji, a w class member initializer stanie się bardzo przydatny, zwłaszcza jeśli masz kilka Kor. Oto dobry link, aby uzyskać więcej informacji: http://www.stroustrup.com/C++11faq. html # member-INIT

Po edycji: zgodnie z Twoim kodem używasz C++11. Według mojej wiedzy jest tylko kilka informacji na temat dobrych praktyk dotyczących nowych możliwości, ale IMHO in class member initializer są bardzo przydatne do skoncentrowania inicjalizacji w jednym miejscu, co zmniejsza złożoność i typowanie

 10
Author: Martin,
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
2014-03-18 14:07:56

Inicjalizacja w nagłówkach ma główne zalety utrzymywania kodu bardziej lokalnego i łatwego do zrozumienia. Oszczędza również trochę pisania.

Główną wadą, moim zdaniem, jest potrzeba dodania większej liczby nagłówków, aby uzyskać dostęp do konstruktorów. Prosta deklaracja forward nie wystarczy, aby kompilacja trwała dłużej.

 2
Author: Christopher Oezbek,
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
2012-07-21 18:50:55