Co oznacza "default" po deklaracji funkcji klasy?

Widziałem default używane obok deklaracji funkcji w klasie. Co to robi?

class C {
  C(const C&) = default;
  C(C&&) = default;
  C& operator=(const C&) & = default;
  C& operator=(C&&) & = default;
  virtual ~C() { }
};
Author: Paul Manta, 2011-06-28

5 answers

Jest to nowa funkcja C++11 .

Oznacza to, że chcesz użyć wygenerowanej przez kompilator wersji tej funkcji, więc nie musisz podawać ciała.

Możesz również użyć = delete, aby określić, że nie chcesz, aby kompilator generował tę funkcję automatycznie.

Wraz z wprowadzeniem konstruktorów move i operatorów przyporządkowania move, reguły generowania automatycznych wersji konstruktorów, destruktorów i operatorów przyporządkowania mają stają się dość złożone. Używanie = default i = delete ułatwia sprawę, ponieważ nie musisz pamiętać zasad: po prostu mówisz to,co chcesz.

 273
Author: Peter Alexander,
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-06-26 20:05:33

Jest to nowa funkcja C++0x, która mówi kompilatorowi, aby stworzył domyślną wersję odpowiedniego konstruktora lub operatora przypisania, tzn. tego, który po prostu wykonuje akcję Kopiuj lub przenieś dla każdego elementu. Jest to przydatne, ponieważ konstruktor move nie zawsze jest generowany domyślnie (np. jeśli masz własny Destruktor), w przeciwieństwie do konstruktora kopiującego( i podobnie do przypisania), ale jeśli nie ma nic nietrywialnego do napisania, lepiej pozwolić kompilatorowi się tym zająć, niż przeliterować za każdym razem.

Zauważ również, że konstruktor domyślny nie zostanie wygenerowany, jeśli podasz inny konstruktor inny niż domyślny. Jeśli nadal chcesz konstruktora domyślnego, możesz użyć tej składni, aby kompilator go stworzył.

Jako kolejny przypadek użycia, istnieje kilka sytuacji, w których Konstruktor kopiujący nie byłby generowany domyślnie(np. jeśli podasz własny konstruktor move). Jeśli nadal chcesz wersję domyślną, możesz poprosić o nią za pomocą tego składnia.

Szczegóły w sekcji 12.8 normy.

 49
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
2011-06-28 07:19:33

JEST NOWY W C++11, Zobacz Tutaj . Może to być bardzo przydatne, jeśli zdefiniowałeś jeden konstruktor, ale chcesz użyć domyślnych dla innych. Pre-C++11 musisz zdefiniować wszystkie konstruktory po zdefiniowaniu jednego, nawet jeśli są one równoważne z domyślnymi.

Zauważ również, że w pewnych sytuacjach niemożliwe jest dostarczenie domyślnego konstruktora zdefiniowanego przez użytkownika, który zachowuje się tak samo, jak kompilator zsyntetyzowany pod inicjalizacją default i value. default

 21
Author: juanchopanza,
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
2016-08-17 09:19:18

Innym przypadkiem użycia, którego nie widzę w tych odpowiedziach, jest to, że łatwo pozwala zmienić widoczność konstruktora. Na przykład, może chcesz, aby Klasa znajomego miała dostęp do konstruktora kopiującego, ale nie chcesz, aby był on publicznie dostępny.

 11
Author: dshin,
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
2016-01-05 06:25:22

C++17 n4659 standard draft

Https://github.com/cplusplus/draft/blob/master/papers/n4659.pdf 11.4.2 "jawnie domyślne funkcje":

1 Definicja funkcji postaci:

attribute-specifier-seq opt decl-specifier-seq opt declarator virt-specifier-seq opt = default ;

Nazywa się jawnie domyślną definicją. Funkcja, która jest jawnie domyślna

  • (1.1) - być funkcją członka specjalnego,

  • (1.2) - mieć ten sam zadeklarowany typ funkcji (z wyjątkiem możliwego różniących się ref-kwalifikacjami i poza tym, że w w przypadku konstruktora kopiującego lub operatora kopiowania, parametr Typ może być " odniesieniem do non-const T", gdzie T jest nazwą klasy funkcji członowej) tak, jakby została ona zadeklarowana w sposób niejawny, i

  • (1.3) - nie ma domyślnych argumentów.

2 jawnie domyślna funkcja, która nie jest zdefiniowana jako usunięta, może być zadeklarowana jako constexpr tylko wtedy, gdy zostały niejawnie zadeklarowane jako constexpr. Jeśli funkcja jest wyraźnie domyślna w pierwszej deklaracji, to jest w sposób dorozumiany uważany za constexpr, jeśli deklaracja dorozumiana byłaby.

3 Jeśli funkcja, która jest jawnie defaulowana, jest zadeklarowana ze specyfikatorem noexcept, który nie generuje tego samego Specyfikacja wyjątku jako domyślna deklaracja (18.4), następnie

  • (3.1) - Jeśli funkcja jest wyraźnie domyślna w pierwszej deklaracji, jest zdefiniowana jako usunięta;

  • (3.2) - w przeciwnym razie program jest źle uformowany.

4 [ Przykład:

struct S {
  constexpr S() = default;            // ill-formed: implicit S() is not constexpr
  S(int a = 0) = default;             // ill-formed: default argument
  void operator=(const S&) = default; // ill-formed: non-matching return type
  ~ S() noexcept(false) = default;    // deleted: exception specification does not match
private:
  int i;                              // OK: private copy constructor
  S(S&);
};
S::S(S&) = default;                   // OK: defines copy constructor

- end example]

5 Funkcje jawnie zadeklarowane i niejawnie zadeklarowane są zbiorczo nazywane funkcjami domyślnymi, oraz realizacja powinna zawierać dla nich dorozumiane definicje (15.1 15.4, 15.8), co może oznaczać definiowanie je jako usunięte. Funkcja jest dostarczana przez użytkownika, jeśli jest zadeklarowana przez użytkownika, a nie jawnie domyślna lub usunięta na jego pierwsza deklaracja. Funkcja jawnie defaulted (tj. jawnie defaulted po jej pierwszym declaration) jest zdefiniowana w punkcie, w którym jest jawnie niewykonana; jeśli taka funkcja jest niejawnie zdefiniowana jako usunięto, program jest źle uformowany. [Uwaga: deklarowanie funkcji jako domyślnej po jej pierwszej deklaracji może zapewnia wydajne wykonanie i zwięzłą definicję, jednocześnie umożliwiając stabilny interfejs binarny dla rozwijającego się kodu baza. - Uwaga końcowa]

6 [ Przykład:

struct trivial {
  trivial() = default;
  trivial(const trivial&) = default;
  trivial(trivial&&) = default;
  trivial& operator=(const trivial&) = default;
  trivial& operator=(trivial&&) = default;
  ~ trivial() = default;
};
struct nontrivial1 {
  nontrivial1();
};
nontrivial1::nontrivial1() = default;       // not first declaration

- end example]

Wtedy pytanie jest oczywiście, które funkcje mogą być niejawnie zadeklarowane i kiedy to się dzieje, co wyjaśniłem w:

 1
Author: Ciro Santilli TRUMP BAN IS BAD,
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
2018-11-15 10:10:46