Sök…
Introduktion
Nyckelord har en fast betydelse definierad av C ++ -standarden och kan inte användas som identifierare. Det är olagligt att omdefiniera nyckelord med hjälp av förprocessorn i någon översättningsenhet som innehåller en standardbibliotekshuvud. Emellertid förlorar nyckelord sin speciella betydelse inuti attribut.
Syntax
- asm ( string-letteral );
- noexcept ( uttryck ) // betyder 1
- noexcept ( konstant uttryck ) // betyder 2
- noexcept // betyder 2
- storlek av unary-expression
- storlek av ( typ-id )
- sizeof ... ( identifierare ) // sedan C ++ 11
- typnamn kapslad identifierare identifierare // betydelse 1
- typnamn kapslad-namn-specifik mall ( opt ) enkel-mall-id // betydelse 1
- Typename identifierare (opt) // betyder 2
- typnamn ... identifierare ( opt ) // betyder 2; sedan C ++ 11
- Typename identifierare (opt) = typ-id // betyder 2
- mall < mall-parameter-lista > typnamn ... ( opt ) identifierare ( opt ) // betydelse 3
- mall <mall-parameterlista> Typename identifierare (opt) = id-uttryck // vilket betyder 3
Anmärkningar
Den fullständiga listan med nyckelord är enligt följande:
-
alignas
(sedan C ++ 11) -
alignof
(sedan C ++ 11) -
asm
-
auto
: sedan C ++ 11 , före C ++ 11 -
bool
-
break
-
case
-
catch
-
char
-
char16_t
(sedan C ++ 11) -
char32_t
(sedan C ++ 11) -
class
-
const
-
constexpr
(sedan C ++ 11) -
const_cast
-
continue
-
decltype
(sedan C ++ 11) -
default
-
delete
för minneshantering , för funktioner (sedan C ++ 11) -
do
-
double
-
dynamic_cast
-
else
-
enum
-
explicit
-
export
-
extern
som deklarationsspecifikation , i kopplingsspecifikation , för mallar -
false
-
float
-
for
-
friend
-
goto
-
if
-
inline
för funktioner , för namnutrymmen (sedan C ++ 11), för variabler (sedan C ++ 17) -
int
-
long
-
mutable
-
namespace
-
new
-
noexcept
(sedan C ++ 11) -
nullptr
(sedan C ++ 11) -
operator
-
private
-
protected
-
public
-
register
-
reinterpret_cast
-
return
-
short
-
signed
-
sizeof
-
static
-
static_assert
(sedan C ++ 11) -
static_cast
-
struct
-
switch
-
template
-
this
-
thread_local
(sedan C ++ 11) -
throw
-
true
-
try
-
typedef
-
typeid
-
typename
-
union
-
unsigned
-
using
att förklara ett namn , alias ett namnområde , alias en typ -
virtual
för funktioner , för basklasser -
void
-
volatile
-
wchar_t
-
while
Tokenens final
och override
är inte nyckelord. De kan användas som identifierare och har speciell betydelse endast i vissa sammanhang.
Tokens and
, and_eq
, bitand
, bitor
, compl
, not
, not_eq
or
, or_eq
, xor
och xor_eq
är alternativa stavningar för &&
, &=
, &
, |
, ~
!
, !=
, ||
, |=
, ^
respektive ^=
. Standarden behandlar dem inte som nyckelord, men de är nyckelord för alla syften, eftersom det är omöjligt att omdefiniera dem eller använda dem för att betyda något annat än de operatörer de representerar.
Följande ämnen innehåller detaljerade förklaringar av många av nyckelorden i C ++, som tjänar grundläggande syften som att namnge grundtyper eller kontrollera körningsflödet.
asm
asm
nyckelordet tar en enda operand, som måste vara en strängbokstavlig. Den har en implementeringsdefinierad betydelse, men överförs vanligtvis till implementeringens monterare, varvid monterarens utgång införlivas i översättningsenheten.
asm
uttalandet är en definition , inte ett uttryck , så det kan visas antingen i blockomfång eller namnområde (inklusive global räckvidd). Eftersom inline-montering inte kan begränsas av reglerna för C ++ asm
kanske asm
inte visas i en constexpr
funktion.
Exempel:
[[noreturn]] void halt_system() {
asm("hlt");
}
explicit
När den tillämpas på en konstruktör med ett enda argument, förhindrar den konstruktören från att utföra implicita konverteringar.
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
Eftersom C ++ 11 införde initialiseringslistor, i C ++ 11 och senare, kan
explicit
tillämpas på en konstruktör med valfritt antal argument, med samma betydelse som i fallet med en enda argument.struct S { explicit S(int x, int y); }; S f() { return {12, 34}; // ill-formed return S{12, 34}; // ok }
När den tillämpas på en konverteringsfunktion förhindrar den att konverteringsfunktionen används för att utföra implicita konverteringar.
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
En unary operatör som avgör om utvärderingen av dess operand kan föröka ett undantag. Observera att kropparna med kallade funktioner inte undersöks, så
noexcept
kan ge falska negativ. Operanden utvärderas inte.#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 }
I detta exempel, även om
bar()
aldrig kan kasta ett undantag, ärnoexcept(bar())
fortfarande felaktigt eftersom det faktum attbar()
inte kan sprida ett undantag inte har uttryckligen angetts.När du deklarerar en funktion anger du om funktionen kan sprida ett undantag eller inte. Enbart förklarar den att funktionen inte kan sprida ett undantag. Med ett parenteserat argument förklarar det att funktionen kan eller inte kan sprida ett undantag beroende på sanningsvärdet för argumentet.
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&) {} }
I det här exemplet har vi förklarat att
f4
,f5
ochf6
inte kan sprida undantag. (Även om ett undantag kan kastas under körning avf6
, fångas det och får inte sprida sig ur funktionen.) Vi har förklarat attf2
kan sprida ett undantag. Närnoexcept
specifikatorn utelämnas motsvarar dennoexcept(false)
, så vi har implicit förklarat attf1
ochf3
kan sprida undantag, även om undantag faktiskt inte kan kastas under exekveringen avf3
.
Huruvida en funktion är noexcept
eller inte är en del av funktionens typ: det vill säga i exemplet ovan har f1
, f2
och f3
olika typer från f4
, f5
och f6
. Därför är noexcept
också viktigt i funktionspekare, mallargument osv.
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
När det följs av ett kvalificerat namn anger
typename
att det är namnet på en typ. Detta krävs ofta i mallar, i synnerhet när den kapslade namnspecifikationen är en annan beroende typ än den aktuella inställningen. I det här exemplet berorstd::decay<T>
på mallparameternT
, så för att namnge den kapsladetype
måste vi prefixera hela kvalificerade namnet medtypename
. För mer deatils, se Var och varför måste jag sätta "mall" och "typnamn" nyckelorden?template <class T> auto decay_copy(T&& r) -> typename std::decay<T>::type;
Introducerar en typparameter i deklarationen av en mall . I detta sammanhang är det utbytbart med
class
.template <typename T> const T& min(const T& x, const T& y) { return b < a ? b : a; }
typename
kan också användas när du deklarerar en mallmallparameter , före parameterns namn, precis somclass
.template <template <class T> typename U> void f() { U<int>::do_it(); U<double>::do_it(); }
storlek av
En unary operatör som ger storleken i byte på sin operand, vilket kan vara antingen ett uttryck eller en typ. Om operanden är ett uttryck utvärderas den inte. Storleken är ett konstant uttryck för typen std::size_t
.
Om operanden är en typ måste den ha parentes.
- Det är olagligt att tillämpa
sizeof
på en funktionstyp. - Det är olagligt att tillämpa
sizeof
på en ofullständig typ, inklusivevoid
. - Om sizeof tillämpas på en referenstyp
T&
ellerT&&
, motsvarar densizeof(T)
. - När
sizeof
tillämpas på ensizeof
ger det antalet byte i ett komplett objekt av den typen, inklusive eventuella stoppningsbyte i mitten eller i slutet. Därför kan ettsizeof
uttryck aldrig ha ett värde på 0. Se layout av objekttyper för mer information. -
char
,signed char
ochunsigned char
typer har en storlek på 1. Omvänt definieras en byte som mängden minne som krävs för att lagra ettchar
objekt. Det betyder inte nödvändigtvis 8 bitar, eftersom vissa system harchar
objekt som är längre än 8 bitar.
Om expr är ett uttryck, är sizeof(
expr )
ekvivalent med sizeof(T)
där T
är typen av 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...
ger antalet element i ett parameterpaket.
template <class... T>
void f(T&&...) {
std::cout << "f was called with " << sizeof...(T) << " arguments\n";
}
Olika nyckelord
ogiltig C ++
När det används som en funktion avkastningstyp, anger det ogiltiga nyckelordet att funktionen inte returnerar ett värde. När det används för en funktions parameterlista anger void att funktionen inte tar några parametrar. När det används i deklarationen för en pekare, anger tomrum att pekaren är "universal".
Om en pekartyp är ogiltig * kan pekaren peka på alla variabler som inte deklareras med const eller volatile nyckelord. En ogiltig pekare kan inte avskaffas om den inte kastas till en annan typ. En ogiltig pekare kan konverteras till någon annan typ av datapekare.
En ogiltig pekare kan peka på en funktion, men inte till en klassmedlem i 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;
Flyktiga C ++
En typkvalificering som du kan använda för att förklara att ett objekt kan modifieras i programmet av hårdvaran.
volatile declarator ;
virtuell C ++
Det virtuella nyckelordet förklarar en virtuell funktion eller en virtuell basklass.
virtual [type-specifiers] member-function-declarator virtual [access-specifier] base-class-name
parametrar
typspecifikationer Anger returtypen för den virtuella medlemsfunktionen.
medlem-funktion-deklarator Förklarar en medlemsfunktion.
access-specificier Definierar åtkomstnivån till basklassen, offentligt, skyddat eller privat. Kan visas före eller efter det virtuella nyckelordet.
basklassklassnamn Identifierar en tidigare deklarerad klasstyp
den här pekaren
Pekaren är en pekare som endast är tillgänglig inom de icke-statiska medlemsfunktionerna av en klass, struktur eller facklig typ. Den pekar på objektet för vilket medlemsfunktionen kallas. Statiska medlemsfunktioner har inte den här pekaren.
this->member-identifier
Ett objekt är den här pekaren är inte en del av själva objektet; det återspeglas inte i resultatet av en storlekof-uttalande på objektet. I stället, när en icke-statisk medlemsfunktion kallas för ett objekt, skickas objektets adress av kompilatorn som ett doldt argument till funktionen. Följande funktion ringer till exempel:
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
prova, kasta och fånga uttalanden (C ++)
- För att implementera undantagshantering i C ++ använder du försök, kasta och fånga uttryck.
- Använd först ett försöksblock för att bifoga ett eller flera uttalanden som kan kasta ett undantag.
- Ett kastuttryck signalerar att ett exceptionellt tillstånd - ofta ett fel - har inträffat i ett försöksblock. Du kan använda ett objekt av valfri typ som operand för ett kastuttryck. Vanligtvis används detta objekt för att kommunicera information om felet. I de flesta fall rekommenderar vi att du använder std :: undantagsklassen eller en av de härledda klasserna som definieras i standardbiblioteket. Om en av dessa inte är lämplig, rekommenderar vi att du hämtar din egen undantagsklass från std :: undantag.
- För att hantera undantag som kan kastas, implementera ett eller flera fångstblock omedelbart efter ett försöksblock. Varje fångstblock anger vilken typ av undantag den kan hantera.
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");
// ...
}
Koden efter provklausulen är den skyddade delen av koden. Kastuttrycket kastar - det vill säga höjer - ett undantag. Kodblocket efter fångstklausulen är undantagshanteraren. Det här är hanteraren som fångar det undantag som kastas om typerna i kast- och fångstuttryck är kompatibla.
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;
}
vän (C ++)
Under vissa omständigheter är det bekvämare att ge medlemmarnas åtkomst till funktioner som inte är medlemmar i en klass eller för alla medlemmar i en separat klass. Endast klassimplementören kan förklara vem dess vänner är. En funktion eller klass kan inte förklara sig som en vän till någon klass. I en klassdefinition använder du vän-nyckelordet och namnet på en icke-medlemsfunktion eller annan klass för att ge den åtkomst till de privata och skyddade medlemmarna i din klass. I en malldefinition kan en typparameter förklaras som en vän.
Om du förklarar en vänfunktion som inte tidigare har deklarerats exporteras den funktionen till det bifogade icke-klassade omfånget.
class friend F friend F; class ForwardDeclared;// Class name is known. class HasFriends { friend int ForwardDeclared::IsAFriend();// C2039 error expected };
vänfunktioner
En vänfunktion är en funktion som inte är medlem i en klass men har tillgång till klassens privata och skyddade medlemmar. Vänfunktioner anses inte klassmedlemmar; de är normala externa funktioner som ges speciella åtkomstbehörigheter.
Vänner är inte inom klassens omfattning och de kallas inte med medlemmarvalsoperatörer (. Och ->) om de inte är medlemmar i en annan klass.
En vänfunktion deklareras av klassen som ger åtkomst. Vändeklarationen kan placeras var som helst i klassdeklarationen. Det påverkas inte av nyckelorden för åtkomstkontroll.
#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 }
Klassmedlemmar som vänner
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