Class declaration
Klassen sind benutzerdefinierte Typen, definiert durch einen Klassen-Spezifizierer, der in der decl-specifier-seq der Deklarations -Syntax erscheint.
Inhalt
SyntaxDie Klassenspezifikation hat die folgende Syntax:
1) Benannte Klassendefinition
2) Unbenannte Klassendefinition
VorwärtsdeklarationEine Deklaration der folgenden Form
Deklariert einen Klassentyp, der später in diesem Gültigkeitsbereich definiert wird. Bis die Definition erscheint, hat dieser Klassenname unvollständigen Typ . Dies erlaubt Klassen, die sich gegenseitig referenzieren: class Vector; // Vorwärtsdeklaration class Matrix { // ... friend Vector operator*(const Matrix&, const Vector&); }; class Vector { // ... friend Vector operator*(const Matrix&, const Vector&); }; und wenn eine bestimmte Quelldatei nur Zeiger und Referenzen auf die Klasse verwendet, ermöglicht dies die Reduzierung von #include Abhängigkeiten: // In MyStruct.h #include <iosfwd> // enthält Vorwärtsdeklaration von std::ostream struct MyStruct { int value; friend std::ostream& operator<<(std::ostream& os, const S& s); // Definition bereitgestellt in MyStruct.cpp Datei, die #include <ostream> verwendet }; Wenn eine Vorwärtsdeklaration im lokalen Gültigkeitsbereich erscheint, verdeckt sie die zuvor deklarierte Klasse, Variable, Funktion und alle anderen Deklarationen desselben Namens, die in umschließenden Gültigkeitsbereichen erscheinen können: struct s { int a; }; struct s; // tut nichts (s ist bereits in diesem Gültigkeitsbereich definiert) void g() { struct s; // Vorwärtsdeklaration einer neuen, lokalen Struktur "s" // dies verdeckt die globale Struktur s bis zum Ende dieses Blocks s* p; // Zeiger auf lokale Struktur s struct s { char* p; }; // Definition der lokalen Struktur s } Beachten Sie, dass ein neuer Klassenname auch durch einen elaborated type specifier eingeführt werden kann, der als Teil einer anderen Deklaration erscheint, aber nur wenn name lookup keine zuvor deklarierte Klasse mit demselben Namen finden kann. class U; namespace ns { class Y f(class T p); // deklariert Funktion ns::f und deklariert ns::T und ns::Y class U f(); // U bezieht sich auf ::U // kann Zeiger und Referenzen auf T und Y verwenden Y* p; T* q; } MemberspezifikationDie Memberspezifikation, oder der Body einer Klassendefinition, ist eine in geschweifte Klammern eingeschlossene Sequenz einer beliebigen Anzahl der folgenden Elemente:
1)
Elementdeklarationen der Form
Diese Deklaration kann statische und nicht-statische Datenelemente und Elementfunktionen , Element- Typdefinitionen , Element- Aufzählungen sowie geschachtelte Klassen deklarieren. Es kann sich auch um eine Friend-Deklaration handeln. class S { int d1; // non-static data member int a[10] = {1, 2}; // non-static data member with initializer (C++11) static const int d2 = 1; // static data member with initializer virtual void f1(int) = 0; // pure virtual member function std::string d3, *d4, f2(int); // two data members and a member function enum { NORTH, SOUTH, EAST, WEST }; struct NestedS { std::string s; } d5, *d6; typedef NestedS value_type, *pointer_type; };
2)
Funktionsdefinitionen, die sowohl
Member-Funktionen
als auch
Friend-Funktionen
deklarieren und definieren.
Ein Semikolon nach einer Member-Funktionsdefinition ist optional.
Alle Funktionen, die innerhalb eines Klassenkörpers definiert sind, sind automatisch
inline
, es sei denn, sie sind an ein
benanntes Modul
gebunden
(seit C++20)
.
class M { std::size_t C; std::vector<int> data; public: M(std::size_t R, std::size_t C) : C(C), data(R*C) {} // constructor definition int operator()(std::size_t r, std::size_t c) const // member function definition { return data[r * C + c]; } int& operator()(std::size_t r, std::size_t c) // another member function definition { return data[r * C + c]; } };
3)
Zugriffsspezifizierer
public:
,
protected:
, und
private:
class S { public: S(); // public constructor S(const S&); // public copy constructor virtual ~S(); // public virtual destructor private: int* ptr; // private data member };
4)
Using-Deklarationen
:
class Base { protected: int d; }; class Derived : public Base { public: using Base::d; // mache Bases geschütztes Mitglied d zu einem öffentlichen Mitglied von Derived using Base::Base; // erbe alle Konstruktoren der Basisklassen (C++11) };
5)
static_assert
Deklarationen:
template<typename T> struct Foo { static_assert(std::is_floating_point<T>::value, "Foo<T>: T must be floating point"); };
6)
Deklarationen von Member-Templates
:
struct S { template<typename T> void f(T&& n); template<class CharT> struct NestedS { std::basic_string<CharT> s; }; };
Lokale KlassenEine Klassendeklaration kann im Rumpf einer Funktion erscheinen, in welchem Fall sie eine lokale Klasse definiert. Der Name einer solchen Klasse existiert nur innerhalb des Funktionsbereichs und ist von außen nicht zugänglich.
Diesen Code ausführen
#include <algorithm> #include <iostream> #include <vector> int main() { std::vector<int> v{1, 2, 3}; struct Local { bool operator()(int n, int m) { return n > m; } }; std::sort(v.begin(), v.end(), Local()); // since C++11 for (int n : v) std::cout << n << ' '; std::cout << '\n'; } Ausgabe: 3 2 1 SchlüsselwörterFehlerberichteDie folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
Siehe auch
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||