수색…
소개
키워드는 C ++ 표준에 정의 된 고정 된 의미를 가지며 식별자로 사용할 수 없습니다. 표준 라이브러리 헤더가 포함 된 번역 단위에서 전 처리기를 사용하여 키워드를 재정의하는 것은 불법입니다. 그러나 키워드는 특성 내에서 특별한 의미를 잃습니다.
통사론
- asm ( 문자열 리터럴 );
- noexcept ( 표현식 ) // 의미 1
- noexcept ( 상수 표현 ) // 의미 2
- noexcept // 의미 2
- 단항 식 크기
- sizeof ( 유형 -id )
- sizeof ... ( 식별자 ) // 이후 C ++ 11
- typename 중첩 된 이름 지정자 식별자 // 의미 1
- typename 중첩 이름 지정자 템플릿 ( opt ) simple-template-id // 의미 1
- typename 식별자 ( opt ) // 의미 2
- typename ... 식별자 ( opt ) // 의미 2; 이후 C ++ 11
- typename 식별자 ( opt ) = type-id // 의미 2
- template < template-parameter-list > typename ... ( opt ) 식별자 ( opt ) // 의미 3
- template < template-parameter-list > typename 식별자 ( opt ) = id-expression // 의미 3
비고
전체 키워드 목록은 다음과 같습니다.
-
alignas
(C ++ 11 이후) -
alignof
(C ++ 11 이후) -
asm
-
auto
: C ++ 11 이전, C ++ 11 이전 -
bool
-
break
-
case
-
catch
-
char
-
char16_t
(C ++ 11 이후) -
char32_t
(C ++ 11 이후) -
class
-
const
-
constexpr
(C ++ 11 이후) -
const_cast
-
continue
-
decltype
(C ++ 11 이후) -
default
- 함수를 위한 메모리 관리 를 위한
delete
(C ++ 11 이후) -
do
-
double
-
dynamic_cast
-
else
-
enum
-
explicit
-
export
-
extern
을 선언 지정자로 , 연결 지정 에서 템플릿 용으로 사용합니다. -
false
-
float
-
for
-
friend
-
goto
-
if
- 함수 를 위한
inline
, 네임 스페이스 (C ++ 11 이후), 변수 (C ++ 17 이후) -
int
-
long
-
mutable
-
namespace
-
new
-
noexcept
(C ++ 11 이후) -
nullptr
(C ++ 11 이후) -
operator
-
private
-
protected
-
public
-
register
-
reinterpret_cast
-
return
-
short
-
signed
-
sizeof
-
static
-
static_assert
(C ++ 11 이후) -
static_cast
-
struct
-
switch
-
template
-
this
-
thread_local
(C ++ 11 이후) -
throw
-
true
-
try
-
typedef
-
typeid
-
typename
-
union
-
unsigned
-
using
이름을 재 선언하는 것은 , 네임 스페이스를 별칭으로 , 유형을 별명 - 함수 를 위한
virtual
클래스 , 기본 클래스 -
void
-
volatile
-
wchar_t
-
while
final
및 override
의 토큰은 키워드가 아닙니다. 식별자로 사용할 수 있으며 특정 상황에서만 특별한 의미가 있습니다.
토큰 and
and_eq
, bitand
, bitor
, compl
, not
, not_eq
or
or_eq
, xor
및 xor_eq
는 &&
, &=
, &
, |
의 대체 철자입니다. , ~
!
, !=
, ||
, |=
, ^
및 ^=
과 같이 ^=
있습니다. 이 표준은 키워드를 키워드로 취급하지 않지만, 키워드를 재정의하거나 그 연산자가 나타내는 연산자 이외의 다른 의미로는 사용할 수 없기 때문에 모든 의도와 목적을위한 키워드입니다.
다음 항목에는 C ++의 많은 키워드에 대한 자세한 설명이 포함되어 있으며 기본 유형의 이름 지정 또는 실행 흐름 제어와 같은 기본적인 용도로 사용됩니다.
asm
asm
키워드는 문자열 리터럴이어야하는 단일 피연산자를 사용합니다. 이것은 구현 정의의 의미를 가지지 만, 전형적으로 구현체의 어셈블러로 전달되며, 어셈블러의 출력은 변환 유닛에 통합됩니다.
asm
문은 표현식이 아닌 정의 이므로 블록 범위 또는 네임 스페이스 범위 (전역 범위 포함)에 나타날 수 있습니다. 그러나 인라인 어셈블리는 C ++ 언어의 규칙에 의해 제약 될 수 없으므로 asm
은 constexpr
함수 내에 나타나지 않을 수 있습니다.
예:
[[noreturn]] void halt_system() {
asm("hlt");
}
명백한
단일 인수 생성자에 적용되면 암시 적 변환을 수행하는 데 해당 생성자가 사용되지 않습니다.
class MyVector { public: explicit MyVector(uint64_t size); }; MyVector v1(100); // ok uint64_t len1 = 100; MyVector v2{len1}; // ok, len1 is uint64_t int len2 = 100; MyVector v3{len2}; // ill-formed, implicit conversion from int to uint64_t
C ++ 11에서는 이니셜 라이저 목록을 도입 했으므로 C ++ 11 이상에서는
explicit
인수를 단일 인수의 경우와 같은 의미로 여러 인수를 사용하여 생성자에 적용 할 수 있습니다.struct S { explicit S(int x, int y); }; S f() { return {12, 34}; // ill-formed return S{12, 34}; // ok }
변환 함수에 적용되면 해당 변환 함수를 사용하여 암시 적 변환을 수행 할 수 없습니다.
class C { const int x; public: C(int x) : x(x) {} explicit operator int() { return x; } }; C c(42); int x = c; // ill-formed int y = static_cast<int>(c); // ok; explicit conversion
noexcept
피연산자의 평가가 예외를 전파 할 수 있는지 여부를 결정하는 단항 연산자입니다. 호출 된 함수의 본문은 검사되지 않으므로
noexcept
가 false negative를 생성 할 수 있습니다. 피연산자는 평가되지 않습니다.#include <iostream> #include <stdexcept> void foo() { throw std::runtime_error("oops"); } void bar() {} struct S {}; int main() { std::cout << noexcept(foo()) << '\n'; // prints 0 std::cout << noexcept(bar()) << '\n'; // prints 0 std::cout << noexcept(1 + 1) << '\n'; // prints 1 std::cout << noexcept(S()) << '\n'; // prints 1 }
이 예에서, 비록
bar()
예외, 던질 수 없다noexcept(bar())
여전히 거짓 때문에 사실bar()
예외를 전파 할 수 없습니다 명시 적으로 지정되지 않았습니다.함수를 선언 할 때 함수가 예외를 전파 할 수 있는지 여부를 지정합니다. 혼자서는 함수가 예외를 전파 할 수 없다고 선언합니다. 괄호로 묶인 인수를 사용하여 함수는 인수의 진리 값에 따라 예외를 전파 할 수 있는지 여부를 선언합니다.
void f1() { throw std::runtime_error("oops"); } void f2() noexcept(false) { throw std::runtime_error("oops"); } void f3() {} void f4() noexcept {} void f5() noexcept(true) {} void f6() noexcept { try { f1(); } catch (const std::runtime_error&) {} }
이 예제에서는
f4
,f5
및f6
이 예외를 전파 할 수 없다고 선언했습니다. (f6
실행 중에 예외가 throw 될 수는 있지만 catch되고 함수에서 전파되지 않습니다.)f2
가 예외를 전파 할 수 있다고 선언했습니다. 때noexcept
지정을 생략, 그것은에 해당noexcept(false)
, 그래서 우리는 암시 적으로 선언 한f1
과f3
예외가 실제로 실행하는 동안 발생 될 수 있지만, 예외를 전파 할 수f3
.
함수가 noexcept
인지 아닌지 여부는 함수 유형의 일부입니다. 위의 예에서 f1
, f2
및 f3
은 f4
, f5
및 f6
과 다른 유형입니다. 따라서 noexcept
는 함수 포인터, 템플릿 인수 등에서도 중요합니다.
void g1() {}
void g2() noexcept {}
void (*p1)() noexcept = &g1; // ill-formed, since g1 is not noexcept
void (*p2)() noexcept = &g2; // ok; types match
void (*p3)() = &g1; // ok; types match
void (*p4)() = &g2; // ok; implicit conversion
형식 이름
typename
은 정규화 된 이름 뒤에 형식의 이름을 지정합니다. 이것은 템플릿, 특히 중첩 된 이름 지정자가 현재 인스턴스화가 아닌 종속 유형 인 경우에 종종 필요합니다. 이 예제에서std::decay<T>
는 템플릿 매개 변수T
에 따라 달라 지므로 중첩 된 유형type
이름을 지정하려면 전체 정규화 된 이름 앞에typename
을 접두사로 사용해야합니다. 더 많은 deatils를 보려면 Where와 왜 "템플릿"과 "typename"키워드를 넣어야합니까?를보십시오.template <class T> auto decay_copy(T&& r) -> typename std::decay<T>::type;
템플릿 선언에 형식 매개 변수를 도입합니다. 이런 맥락에서, 그것은
class
와 상호 교환 가능합니다.template <typename T> const T& min(const T& x, const T& y) { return b < a ? b : a; }
typename
은class
와 마찬가지로 매개 변수의 이름 앞에 템플릿 템플릿 매개 변수를 선언 할 때도 사용할 수 있습니다.template <template <class T> typename U> void f() { U<int>::do_it(); U<double>::do_it(); }
크기
피연산자의 크기 (바이트 또는 수식)를 산출하는 단항 연산자입니다. 피연산자가 표현식이면 평가되지 않습니다. 크기는 std::size_t
유형의 상수 표현입니다.
피연산자가 유형이면 괄호로 묶어야합니다.
- 함수 유형에
sizeof
를 적용하는 것은 불법입니다. -
void
포함하여 불완전 유형에sizeof
를 적용하는 것은 불법입니다. - sizeof가 참조 유형
T&
orT&&
되면sizeof(T)
와 동일합니다. -
sizeof
가 클래스 유형에 적용되면 중간 또는 끝에있는 모든 패딩 바이트를 포함하여 해당 유형의 전체 객체에있는 바이트 수가 산출됩니다. 따라서sizeof
표현식의 값은 0이 될 수 없습니다. 자세한 내용 은 객체 유형의 레이아웃 을 참조하십시오. -
char
,signed char
및unsigned char
유형의 크기는 1입니다. 반대로, 바이트는char
객체를 저장하는 데 필요한 메모리 크기로 정의됩니다. 일부 시스템에는 8 비트보다 긴char
객체가 있기 때문에 반드시 8 비트를 의미하지는 않습니다.
expr 이 식인 경우 sizeof(
expr )
는 sizeof(T)
와 같습니다. 여기서 T
는 expr 의 형식입니다 .
int a[100];
std::cout << "The number of bytes in `a` is: " << sizeof a;
memset(a, 0, sizeof a); // zeroes out the array
sizeof...
연산자는 매개 변수 팩의 요소 수를 산출합니다.
template <class... T>
void f(T&&...) {
std::cout << "f was called with " << sizeof...(T) << " arguments\n";
}
다른 키워드
void C ++
함수 반환 형식으로 사용될 때 void 키워드는 함수가 값을 반환하지 않도록 지정합니다. 함수의 매개 변수 목록에 사용되는 경우 void는 함수가 매개 변수를 사용하지 않도록 지정합니다. 포인터를 선언 할 때 void를 사용하면 포인터가 "범용"으로 지정됩니다.
포인터의 타입이 void * 인 경우 포인터는 const 또는 volatile 키워드로 선언되지 않은 변수를 가리킬 수 있습니다. void 포인터가 다른 유형으로 캐스트되지 않는 한 참조 해제 될 수 없습니다. void 포인터는 다른 유형의 데이터 포인터로 변환 될 수 있습니다.
void 포인터는 함수를 가리킬 수 있지만 C ++의 클래스 멤버는 가리킬 수 없습니다.
void vobject; // C2182 void *pv; // okay int *pint; int i; int main() { pv = &i; // Cast optional in C required in C++ pint = (int *)pv;
휘발성 C ++
하드웨어가 프로그램에서 객체를 수정할 수 있음을 선언하는 데 사용할 수있는 유형 한정자입니다.
volatile declarator ;
가상 C ++
virtual 키워드는 가상 함수 또는 가상 기본 클래스를 선언합니다.
virtual [type-specifiers] member-function-declarator virtual [access-specifier] base-class-name
매개 변수
type-specifiers 가상 멤버 함수의 반환 유형을 지정합니다.
member-function-declarator 멤버 함수를 선언합니다.
access-specifier 기본 클래스 인 public, protected 또는 private에 대한 액세스 레벨을 정의합니다. 가상 키워드 앞이나 뒤에 나타날 수 있습니다.
base-class-name 이전에 선언 된 클래스 유형을 식별합니다.
이 포인터
이 포인터는 클래스, 구조체 또는 공용체 유형의 비 정적 멤버 함수 내에서만 액세스 할 수있는 포인터입니다. 이 함수는 멤버 함수가 호출 된 객체를 가리 킵니다. 정적 멤버 함수에는이 포인터가 없습니다.
this->member-identifier
객체의 포인터는 객체 자체의 일부가 아닙니다. 객체에 대한 sizeof 문의 결과에는 반영되지 않습니다. 대신, 비 정적 멤버 함수가 객체에 대해 호출되면 객체의 주소는 컴파일러에 의해 숨겨진 인수로 함수에 전달됩니다. 예를 들어, 다음 함수 호출 :
myDate.setMonth( 3 );
can be interpreted this way:
setMonth( &myDate, 3 );
The object's address is available from within the member function as the this pointer. Most uses of this are implicit. It is legal, though unnecessary, to explicitly use this when referring to members of the class. For example:
void Date::setMonth( int mn )
{
month = mn; // These three statements
this->month = mn; // are equivalent
(*this).month = mn;
}
The expression *this is commonly used to return the current object from a member function:
return *this;
The this pointer is also used to guard against self-reference:
if (&Object != this) {
// do not execute in cases of self-reference
try, throw 및 catch 문 (C ++)
- C ++에서 예외 처리를 구현하려면 try, throw 및 catch 식을 사용합니다.
- 먼저 try 블록을 사용하여 예외를 throw 할 수있는 하나 이상의 명령문을 묶습니다.
- throw 표현식은 try 블록에서 예외적 인 조건 (흔히 오류)이 발생했다는 신호입니다. 임의의 타입의 객체를 throw 표현식의 피연산자로 사용할 수 있습니다. 일반적으로이 개체는 오류에 대한 정보를 전달하는 데 사용됩니다. 대부분의 경우 std :: exception 클래스 또는 표준 라이브러리에 정의 된 파생 클래스 중 하나를 사용하는 것이 좋습니다. 그 중 하나가 적절하지 않으면 std :: exception에서 자신의 예외 클래스를 파생시키는 것이 좋습니다.
- throw 될 수있는 예외를 처리하려면 try 블록 바로 다음에 하나 이상의 catch 블록을 구현하십시오. 각 catch 블록은 처리 할 수있는 예외 유형을 지정합니다.
MyData md;
try {
// Code that could throw an exception
md = GetNetworkResource();
}
catch (const networkIOException& e) {
// Code that executes when an exception of type
// networkIOException is thrown in the try block
// ...
// Log error message in the exception object
cerr << e.what();
}
catch (const myDataFormatException& e) {
// Code that handles another exception type
// ...
cerr << e.what();
}
// The following syntax shows a throw expression
MyData GetNetworkResource()
{
// ...
if (IOSuccess == false)
throw networkIOException("Unable to connect");
// ...
if (readError)
throw myDataFormatException("Format error");
// ...
}
try 절 다음의 코드는 보호 된 코드 섹션입니다. 던지기 표현은 던졌습니다. 즉, 발생 - 예외입니다. catch 절 다음의 코드 블록은 예외 처리기입니다. 이것은 throw 및 catch 표현식의 유형이 호환 가능한 경우에 던져지는 예외를 포착하는 핸들러입니다.
try {
throw CSomeOtherException();
}
catch(...) {
// Catch all exceptions – dangerous!!!
// Respond (perhaps only partially) to the exception, then
// re-throw to pass the exception to some other handler
// ...
throw;
}
친구 (C ++)
경우에 따라 클래스의 멤버가 아닌 함수 나 별도 클래스의 모든 멤버에게 멤버 수준의 액세스 권한을 부여하는 것이 더 편리합니다. 클래스 구현 자만이 친구가 누구인지 선언 할 수 있습니다. 함수 나 클래스는 자신을 모든 클래스의 친구로 선언 할 수 없습니다. 클래스 정의에서 friend 키워드와 비 멤버 함수 또는 다른 클래스의 이름을 사용하여 클래스의 비공개 및 보호 된 멤버에 대한 액세스 권한을 부여합니다. 템플릿 정의에서 형식 매개 변수는 친구로 선언 할 수 있습니다.
이전에 선언되지 않은 friend 함수를 선언하면 해당 함수는 포함 된 비 클래스 범위로 내보내집니다.
class friend F friend F; class ForwardDeclared;// Class name is known. class HasFriends { friend int ForwardDeclared::IsAFriend();// C2039 error expected };
친구 기능
friend 함수는 클래스의 멤버는 아니지만 클래스의 비공개 및 보호 된 멤버에 액세스 할 수있는 함수입니다. 친구 함수는 클래스 멤버로 간주되지 않습니다. 특별 액세스 권한이 부여 된 정상적인 외부 기능입니다.
친구는 클래스 범위에 없으며 다른 클래스의 멤버가 아니면 멤버 선택 연산자 (. 및 ->)를 사용하여 호출되지 않습니다.
friend 함수는 액세스 권한을 부여하는 클래스에 의해 선언됩니다. friend 선언은 클래스 선언의 아무 곳에 나 배치 할 수 있습니다. 액세스 제어 키워드의 영향을받지 않습니다.
#include <iostream> using namespace std; class Point { friend void ChangePrivate( Point & ); public: Point( void ) : m_i(0) {} void PrintPrivate( void ){cout << m_i << endl; } private: int m_i; }; void ChangePrivate ( Point &i ) { i.m_i++; } int main() { Point sPoint; sPoint.PrintPrivate(); ChangePrivate(sPoint); sPoint.PrintPrivate(); // Output: 0 1 }
친구로서의 반원
class B;
class A {
public:
int Func1( B& b );
private:
int Func2( B& b );
};
class B {
private:
int _b;
// A::Func1 is a friend function to class B
// so A::Func1 has access to all members of B
friend int A::Func1( B& );
};
int A::Func1( B& b ) { return b._b; } // OK
int A::Func2( B& b ) { return b._b; } // C2248