Namespaces
Variants

Class declaration

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Class/struct types
Union types

Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

클래스는 사용자 정의 타입으로, 클래스 지정자에 의해 정의되며 선언 구문의 decl-specifier-seq 에 나타납니다.

목차

구문

클래스 지정자는 다음 구문을 가집니다:

class-key attr  (선택 사항) class-head-name class-property-specs  (선택 사항) base-clause  (선택 사항)
{ member-specification }
(1)
class-key attr  (선택 사항) base-clause  (선택 사항)
{ member-specification }
(2)
1) 명명된 클래스 정의
2) 이름 없는 클래스 정의
class-key - 다음 중 하나: class , struct , union . class struct 키워드는 기본 멤버 접근 제어 기본 기본 클래스 접근 제어 를 제외하고 동일합니다. union 인 경우, 선언은 공용체 타입 을 도입합니다.
attr - (C++11부터) 임의의 수의 속성들 , alignas 지정자를 포함할 수 있음
class-head-name - 정의 중인 클래스의 이름, 선택적으로 한정됨
class-property-specs - 다음 지정자들의 목록, 각 지정자는 각 시퀀스에서 최대 한 번만 허용됨.
지정자 효과
final
(C++11부터)
클래스가 파생될 수 없음 을 지정
trivially_relocatable_if_eligible
(C++26부터)
적격일 경우 클래스를 trivial하게 재배치 가능으로 표시
replaceable_if_eligible
(C++26부터)
적격일 경우 클래스를 대체 가능으로 표시
base-clause - 하나 이상의 기본 클래스들과 각각에 사용된 상속 모델의 목록 ( 파생 클래스 참조)
member-specification - 접근 지정자, 멤버 객체 및 멤버 함수 선언과 정의의 목록 ( 아래 참조 )

전방 선언

다음과 같은 형태의 선언

class-key attr identifier ;

이 스코프 내에서 나중에 정의될 클래스 타입을 선언합니다. 정의가 나타나기 전까지 이 클래스 이름은 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);
    // 정의는 #include <ostream>을 사용하는 MyStruct.cpp 파일에서 제공됨
};

전방 선언이 지역 범위에 나타나면, 이는 가립니다 이전에 선언된 클래스, 변수, 함수 및 바깥쪽 범위에 나타날 수 있는 동일한 이름의 모든 다른 선언들을:

struct s { int a; };
struct s; // 아무 동작도 하지 않음 (s는 이미 이 스코프에서 정의됨)
void g()
{
    struct s; // 새로운 지역 struct "s"의 전방 선언
              // 이는 이 블록의 끝까지 전역 struct s를 가림
    s* p; // 지역 struct s를 가리키는 포인터
    struct s { char* p; }; // 지역 struct 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;
}

멤버 명세

멤버 명세, 또는 클래스 정의의 본문 은 다음 중 임의의 개수로 구성된 중괄호로 둘러싸인 시퀀스입니다:

1) 다음 형식의 멤버 선언
attr  (optional) decl-specifier-seq  (optional) member-declarator-list  (optional) ;
attr - (since C++11) 임의의 개수의 attributes
decl-specifier-seq - specifiers 의 시퀀스. 생성자, 소멸자, 사용자 정의 타입 conversion functions 선언에서만 선택적임
member-declarator-list - init-declarator-list 와 유사하지만, 추가적으로 bit-field declaration , pure-specifier , 및 virt-specifier ( override 또는 final ) (since C++11) 를 허용하고, direct-non-list-initialization syntax 는 허용하지 않음

이 선언은 static 및 비정적 data members member functions , 멤버 typedefs , 멤버 enumerations , 및 nested classes 를 선언할 수 있습니다. 또한 friend declaration 일 수도 있습니다.

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) 함수 정의 - 멤버 함수 friend 함수 를 선언하고 정의합니다. 멤버 함수 정의 뒤의 세미콜론은 선택사항입니다. 클래스 본문 안에서 정의된 모든 함수는 자동으로 inline 이 됩니다(단, named module 에 연결된 경우는 제외 (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;
    };
};
7) alias declarations :
template<typename T>
struct identity
{
    using type = T;
};
(C++11부터)
8) deduction guides of member class templates:
struct S
{
    template<class CharT>
    struct NestedS
    {
        std::basic_string<CharT> s;
    };
    template<class CharT>
    NestedS(std::basic_string<CharT>) -> NestedS<CharT>;
};
(C++17부터)
9) 열거형 사용 선언 :
enum class color { red, orange, yellow };
struct highlight
{
    using enum color;
};
(C++20부터)

지역 클래스

함수 본문 내부에 클래스 선언이 나타날 수 있으며, 이 경우 지역 클래스(local class) 를 정의합니다. 이러한 클래스의 이름은 함수 범위 내에서만 존재하며 외부에서는 접근할 수 없습니다.

  • 로컬 클래스의 멤버는 해당 클래스의 정의 내에서만 선언될 수 있으나, 중첩 클래스 인 멤버는 해당 클래스의 가장 가까운 블록 스코프 에서도 선언될 수 있습니다.
  • 로컬 클래스 내에 중첩된 클래스 또한 로컬 클래스입니다.
  • 로컬 클래스는 정적 데이터 멤버를 가질 수 없습니다.
  • 로컬 클래스의 멤버 함수는 링크age를 가지지 않습니다.
  • 로컬 클래스의 멤버 함수는 클래스 본문 내에서 완전히 정의되어야 합니다.
  • 로컬 클래스는 클로저 타입 이 아닌 경우 (C++14부터) 멤버 템플릿을 가질 수 없습니다.
  • 로컬 클래스는 프렌드 템플릿 을 가질 수 없습니다.
  • 로컬 클래스는 클래스 정의 내부에 프렌드 함수 를 정의할 수 없습니다.
  • 함수(멤버 함수 포함) 내부의 로컬 클래스는 외부 함수가 접근할 수 있는 이름들과 동일한 이름들에 접근할 수 있습니다.
  • 지역 클래스는 템플릿 인자로 사용할 수 없었습니다.
(until C++11)

#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

키워드

class , struct , union

결함 보고서

다음 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.

DR 적용 대상 게시된 동작 올바른 동작
CWG 1693 C++98 멤버 선언이 비어 있을 수 없었음 빈 선언 허용됨
CWG 1930 C++98 member-declarator-list decl-specifier-seq
에 저장 클래스 지정자나 cv 한정자가 포함될 때 비어 있을 수 있었음
리스트는 비어 있으면 안 됨
CWG 2890 C++98 중첩 클래스의 멤버 선언 위치가 불명확했음 명확하게 규정됨

참고 항목

C 문서 에 대한 구조체 선언