Class declaration
クラスはユーザー定義型であり、クラス指定子によって定義されます。クラス指定子は decl-specifier-seq 内に現れ、これは 宣言 構文の一部です。
目次構文クラス指定子の構文は以下の通りです:
1) 名前付きクラス定義
2) 名前なしクラス定義
前方宣言以下の形式の宣言
このスコープ内で後ほど定義されるクラス型を宣言します。定義が現れるまで、このクラス名は incomplete type を持ちます。これにより相互参照するクラスが可能になります: class Vector; // 前方宣言 class Matrix { // ... friend Vector operator*(const Matrix&, const Vector&); }; class Vector { // ... friend Vector operator*(const Matrix&, const Vector&); }; また、特定のソースファイルがクラスへのポインタと参照のみを使用する場合、これにより #include 依存関係を減らすことが可能になります: // MyStruct.h内 #include <iosfwd> // std::ostreamの前方宣言を含む struct MyStruct { int value; friend std::ostream& operator<<(std::ostream& os, const S& s); // 定義はMyStruct.cppファイルで提供され、#include <ostream>を使用 }; 前方宣言がローカルスコープに現れた場合、それは以前に宣言されたクラス、変数、関数、および外側のスコープに現れる可能性のある同じ名前のすべての宣言を 隠蔽 します: struct s { int a; }; struct s; // 何もしない(このスコープではsは既に定義済み) void g() { struct s; // 新しいローカル構造体"s"の前方宣言 // これにより、このブロックの終了までグローバル構造体sが隠蔽される s* p; // ローカル構造体sへのポインタ struct s { char* p; }; // ローカル構造体sの定義 } 新しいクラス名は、 elaborated type specifier によって導入されることもあります。これは他の宣言の一部として現れますが、 name lookup が同じ名前を持つ以前に宣言されたクラスを見つけられない場合に限ります。 class U; namespace ns { class Y f(class T p); // 関数ns::fを宣言し、ns::Tとns::Yを宣言する class U f(); // Uは::Uを参照する // TとYへのポインタと参照を使用可能 Y* p; T* q; } メンバー仕様メンバー仕様、またはクラス定義の body は、以下の中から任意の数の要素を中括弧で囲んだシーケンスです:
1)
以下の形式のメンバー宣言
この宣言は static および非staticの データメンバ と メンバ関数 、メンバ typedef 、メンバ 列挙型 、および ネストされたクラス を宣言できる。また friend宣言 にもなり得る。 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)
関数定義 -
メンバー関数
または
フレンド関数
の宣言と定義の両方を行うもの。メンバー関数定義後のセミコロンは省略可能。クラス本体内で定義されるすべての関数は自動的に
inline
となる
(
名前付きモジュール
に属する場合を除く
(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)
アクセス指定子
public:
、
protected:
、および
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宣言
:
class Base { protected: int d; }; class Derived : public Base { public: using Base::d; // BaseのprotectedメンバdをDerivedのpublicメンバにする using Base::Base; // すべての基底クラスのコンストラクタを継承する (C++11) };
5)
static_assert
宣言:
template<typename T> struct Foo { static_assert(std::is_floating_point<T>::value, "Foo<T>: T must be floating point"); };
6)
メンバーテンプレート宣言
:
struct S { template<typename T> void f(T&& n); template<class CharT> struct NestedS { std::basic_string<CharT> s; }; };
`タグ内のC++コードは翻訳せず保持
- HTMLタグ、属性、クラス名は全て保持
- 書式設定は完全に維持
ローカルクラス関数本体の内部でクラス宣言を記述することができ、その場合 local class を定義します。このようなクラスの名前は関数スコープ内でのみ存在し、外部からはアクセスできません。
このコードを実行
#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'; } 出力: 3 2 1 キーワード不具合報告以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。
関連項目
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||