ãã®ç« ã§ã¯ãC++ã®æ ¹æ¬çãªã«ã¼ã«ã解説ããããã®ç« ã®å
容ã¯ãè¨èªã®æ·±ã詳細ã«ã¤ãã¦è§£èª¬ãã¦ããã®ã§ããã¹ã¦ãç解ããå¿
è¦ã¯ãªããå¿
è¦ã«å¿ãã¦åç
§ããã°ããã
C++ã«ã¯ãååã¨ããæ¦å¿µãåå¨ãããå¤æ°ãé¢æ°ãã¯ã©ã¹çã«ã¯ãååãã¤ãããããååã使ãã«ã¯ãå¿
ãããããããããã®ååã宣è¨ããã¦ããªããã°ãªããªãã
宣è¨ã¨ã¯ãããååãããã®ç¿»è¨³åä½ã§ãä½ãæå³ããã®ãã¨ãããã¨ããæ示ããããã«ããã
å®ç¾©ã¨ã¯ãååã®æã示ããã®ããå
·ä½çã«è¨è¿°ãããã¨ã§ããã宣è¨ã¨å®ç¾©ã¯ãå¤ãã®å ´åãåæã«è¡ããããã¨ãå¤ãã®ã§ããã¾ãæèãã¥ããã
// ããã¯é¢æ°ã®å®£è¨
void f( ) ;
// ããã¯é¢æ°ã®å®£è¨ã¨å®ç¾©
void f( ) { }
以ä¸ã®ä¾ã¯ãé¢æ°ã宣è¨ã ããã¦ãå
·ä½çãªå®ç¾©ãããã«ã使ã£ã¦ããã
// é¢æ°ã®å®£è¨
int f( int ) ;
int main()
{
int x = f( 0 ) ;
}
ããã¯ãåé¡ããªãããªããªãã°ãé¢æ°ã使ãã«ã¯ãå¼æ°ãæ»ãå¤ã®åãªã©ã決ã¾ã£ã¦ããããã°ããããã ããã®å ´åããã®é¢æ°ãæã示ãååã¨ãã¦ãfã使ããã¦ããããã®é¢æ° int f( int )ã®ãå
·ä½çãªå®è£
ãã¤ã¾ãããå®ç¾©ãã¯ãåã翻訳åä½ã«ãªãã¦ãæ§ããªããã¤ã¾ããint f( int )ã¯ãå¥ã®ã½ã¼ã¹ã³ã¼ãã§å®ç¾©ããã¦ãããããããªãã
ãã¹ã¦ã®å®ç¾©ã¯ã宣è¨ã§ããã宣è¨ã¯ãå®ç¾©ã§ã¯ãªãå ´åããããå®ç¾©ã§ã¯ãªã宣è¨ã¯ã以ä¸ã®éãã§ããã
é¢æ°å®£è¨ã§ãé¢æ°ã®æ¬ä½ããªãå ´åã
// 宣è¨
void f( int ) ;
// 宣è¨ã¨å®ç¾©
void f( int ) { }
externæå®åã使ã£ã¦ãã¦ãåæååããé¢æ°ã®æ¬ä½ãè¨è¿°ããã¦ããªã宣è¨ã
// 宣è¨
extern int x ;
// 宣è¨ã¨å®ç¾©
int x ;
ãªã³ã±ã¼ã¸æå®ããã¦ãã¦ãåæååããé¢æ°ã®æ¬ä½ãè¨è¿°ããã¦ããªã宣è¨ããã ãã{}ã®ä¸ã®å®£è¨ã«ã¯ãå½±é¿ããªãã
// 宣è¨
extern "C" void f() ;
extern "C"
{
// ããã¯ã宣è¨ã¨å®ç¾©
void f() { }
int x ;
// 宣è¨
void g() ;
extern int y ;
}
ã¯ã©ã¹åã®å®£è¨ã
// ã¯ã©ã¹åã®å®£è¨
class C ;
// ã¯ã©ã¹ã®å®£è¨ã¨å®ç¾©
class C { } ;
ã¯ã©ã¹å®ç¾©ã®ä¸ã®ãstaticãªãã¼ã¿ã¡ã³ãã¼ã®å®£è¨ã
class C
{
// 宣è¨
static int x ;
} ;
// å®ç¾©
int C::x ;
enumåã®å®£è¨
// 宣è¨
enum E ;
// 宣è¨ã¨å®ç¾©
enum E { up, down } ;
typedef宣è¨
// 宣è¨
typedef int type ;
using宣è¨ã¨ãusingãã£ã¬ã¯ãã£ã
namespace NS { void f(){} }
// 宣è¨
using NS::f ;
using namespace NS ;
ã¾ããstatic_assert宣è¨ãã¢ããªãã¥ã¼ã宣è¨ã空宣è¨ã¯ãå®ç¾©ã§ã¯ãªãã
static_assert( true, "" ) ; // 宣è¨
[[ ]] ; // 宣è¨
; // 宣è¨
ODRï¼One definition ruleï¼ã¨ã¯ãå®ç¾©ã¯ååã¨ãã¦ãã²ã¨ã¤ããæ¸ããªãã¨ããã«ã¼ã«ã§ããã
å¤ãã®å ´åãåã宣è¨ã¯ãããã¤ã§ãæ¸ããããã ããå¤æ°ãé¢æ°ãã¯ã©ã¹åãenumåããã³ãã¬ã¼ãã®ãåãå®ç¾©ã¯ãã²ã¨ã¤ããæ¸ããã¨ãã§ããªãã
// åã宣è¨ã¯ããã¤ã§ãæ¸ããã
void f() ; void f() ; void f() ; void f() ;
// å®ç¾©ã¯ã²ã¨ã¤ããæ¸ããªãã
void f() { }
// ã¨ã©ã¼ãå®ç¾©ãéè¤ãã¦ãã
void f() { }
å®ç¾©ã¯ãããã°ã©ã ã®ãã¹ã¦ã®ç¿»è¨³åä½ã§ãä¸ã¤ã§ãªããã°ãªããªãããªãå®ç¾©ã¯ã²ã¨ã¤ããæ¸ããªãã®ããå®ç¾©ãè¤æ°ããã¨ãåé¡ãããããã ã
// å®ç¾©ãäºã¤ããã
int x ;
int x ;
// ã©ã£ã¡ã®xï¼
x = 0 ;
// å®ç¾©ãäºã¤ãã
void f() { }
void f() { }
// ã©ã£ã¡ã®f()ï¼
f() ;
ãã®ãããªåé¡ãé²ãããã«ãå®ç¾©ã¯ãååã¨ãã¦ä¸ã¤ã§ãªããã°ãªããªãã¨ããã¦ããã
ååã¨ãã¦ã¨ããã®ã¯ãä¾å¤ãããã®ã ããããæ¬å½ã«ãå®ç¾©ãä¸ç®æã§ããæ¸ããªãã¨ãå°ããã¨ãããããã¨ãã°ãã¯ã©ã¹ã ã
// 翻訳åä½1 A.cpp
// å®ç¾©
struct C
{
int x ;
} ;
C c ; // OK
// 翻訳åä½2 B.cpp
// 宣è¨
struct C ;
C c ; // ã¨ã©ã¼
翻訳åä½2ã§ãã¯ã©ã¹Cã®å¤æ°ãå®ç¾©ããããã«ã¯ãã¯ã©ã¹Cã¯ãå®ç¾©ããã¦ããªããã°ãªããªãããããããã§ã«ãå¥ã®ç¿»è¨³åä½ã§ãå®ç¾©ã¯æ¸ããã¦ãããB.cppã«ãå®ç¾©ãæ¸ãã¦ãã¾ãã¨ãODRã«éåãããããã¯ä¸ä½ãã©ãããã°ããã®ãã
ãã®ãããC++ã§ã¯ãã¯ã©ã¹åãenumåãå¤é¨ãªã³ã±ã¼ã¸ãæã¤ã¤ã³ã©ã¤ã³é¢æ°ãã¯ã©ã¹ãã³ãã¬ã¼ããå¤é¨ãªã³ã±ã¼ã¸ãæã¤é¢æ°ãã³ãã¬ã¼ããã¯ã©ã¹ãã³ãã¬ã¼ãã®staticãã¼ã¿ã¡ã³ãã¼ãã¯ã©ã¹ãã³ãã¬ã¼ãã®ã¡ã³ãã¼é¢æ°ãå
·ä½çãªåãå®å
¨ã«æå®ãã¦ããªããã³ãã¬ã¼ãã®ç¹æ®åã«éããããæ¡ä»¶ãæºããã°ãå¥ã®ç¿»è¨³åä½ã§ã®ãå®ç¾©ã®éè¤ãèªãã¦ãããããæ¡ä»¶ã¨ã¯ä½ããããã«ã¯ã大ããåãã¦ãäºã¤ããã
åãå®ç¾©ã®ã½ã¼ã¹ã³ã¼ãã¯ãå
¨ãåããã¼ã¯ã³åã§ãããã¨ã
// 翻訳åä½1 A.cpp
struct C
{
int x ;
} ;
// 翻訳åä½2 B.cpp
struct C
{
public : // ã¨ã©ã¼ã
int x ;
} ;
ããã§ã翻訳åä½2ã«ãpublic :ããããã¨ãªãããã¨ãæå³ã¯å¤ãããªããããããå
¨ãåããã¼ã¯ã³åã§ã¯ãªãã®ã§ããã®ããã°ã©ã ã¯ã¨ã©ã¼ã§ããã
å
¨ãåãè¤æ°ã®å®ç¾©ã管çããã®ã¯ã極ãã¦å°é£ã§ããããã®ããããã®ããã«ç¿»è¨³åä½ãã¨ã«å®ç¾©ããªããã°ãªããªãã¯ã©ã¹ããã³ãã¬ã¼ãã¯ãé常ããããã¼ãã¡ã¤ã«ã«è¨è¿°ãã¦ãå¿
è¦ãªç¿»è¨³åä½ãã¨ã«ã#includeãããã
// ãããã¼ãã¡ã¤ã« C.h
struct C
{
int x ;
} ;
// 翻訳åä½1 A.cpp
#include "C.h"
C c ;
// 翻訳åä½2 B.cpp
#include "C.h"
C c ;
å®ç¾©ã®æå³ããããã°ã©ã ä¸ã®ãã¹ã¦ã®ç¿»è¨³åä½ã§ãåãã§ãããã¨ã
å®ç¾©ã®ã½ã¼ã¹ã³ã¼ãããå
¨ãåããã¼ã¯ã³åã§ããããã¨ãã£ã¦ãæå³ãåãã§ããã¨ã¯éããªãã
// ãããã¼ãã¡ã¤ã« C.h
class C
{
void member()
{
f() ; // fã¨ããååã®ãä½ããã®é¢æ°ãå¼ã³åºãã
}
} ;
ãã®ã¯ã©ã¹ãCã¯ãmember()ã¨ããã¡ã³ãã¼é¢æ°ã§ãf()ã¨ããé¢æ°ãå¼ã³åºãã¦ãããã§ã¯ããã®ã¯ã©ã¹ã使ãã³ã¼ããã以ä¸ã®ããã§ããã°ãã©ããªããã
// 翻訳åä½1 A.cpp
namespace A
{ void f() {} }
// f()ã¯A::f()ãå¼ã³åºã
using A::f ;
#include "C.h"
// 翻訳åä½2 B.cpp
namespace B
{ void f() {} }
// f()ã¯B::f()ãå¼ã³åºã
using B::f ;
#include "C.h"
ãããã¼ãã¡ã¤ã«ã«ãã£ã¦ãã¯ã©ã¹Cã®ã½ã¼ã¹ã³ã¼ãã®ãã¼ã¯ã³åã¯ãå
¨ãåããªã®ã«ããã®ä¾ã§ã¯ãå¼ã³åºãé¢æ°ã翻訳åä½ãã¨ã«å¤ãã£ã¦ãã¾ãããã®ãããªã³ã¼ãã¯ã¨ã©ã¼ã§ãããããã°ã©ã ä¸ã®åãå®ç¾©ã¯ãå¿
ãåãæå³ã§ãªããã°ãªããªãã
宣è¨ãããååã«ã¯ããã®ååãæå¹ã«ä½¿ããç¯å²ãåå¨ããããããã宣è¨ç¯å²ï¼declarative regionï¼ãã¹ã³ã¼ãï¼scopeï¼ã¨ããã
int x ;
void f()
{
int y ;
{
int z ;
}
// ããã§ã¯ãããzã¯ä½¿ããªãã
}
// ããã§ã¯ãããyã¯ä½¿ããªãã
// xã¯ãããã§ã使ããã
ããååã¯ãã¹ã³ã¼ãã®ä¸ãªãã°ãå¿
ãåãæå³ã§ããã¨ã¯éããªããååã¯ä¸æ¸ããããå ´åãããã
void f()
{ // ãããã¯1
int x ; // #1
{ // ãããã¯2
int x ; // #2
x = 0 ; // #2ã使ãããã
}
x = 0 ; // #1ã使ãããã
}
ãã®ä¾ã§ã¯ããããã¯1ã§å®£è¨ãããxã¯ããããã¯2ã§ã¯ãå¥ã®å¤æ°ãæã示ãxã«ãé ããã¦ããã
ãã®ããã«ãã¹ã³ã¼ãããã¹ãããå ´åãå¤å´ã®ã¹ã³ã¼ãã®ååããå
å´ã®ã¹ã³ã¼ãã®ååã«é ããã¦ãã¾ããã¨ãããã
ã¹ã³ã¼ãã«ã¯ãããã¤ãã®ç¨®é¡ããããããã詳ãã説æããåã«ãã¾ãã宣è¨ãããååã¯ãã©ãããæå¹ãªã®ãã¨ãããã¨ããæããã«ãã¦ãããªããã°ãªããªãããã®ãååãæå¹ã«ãªãå§ã¾ãã®å ´æãã宣è¨å ´æï¼Point of declarationï¼ã¨ãããååã¯ã宣è¨ã®ããç´å¾ããæå¹ã«ãªãã
int x ; // 宣è¨å ´æ
// ãããããxã使ããã
宣è¨å ´æã¯ãåæååããããåã§ããã
int x /*ããããååxã¯æå¹*/ = x ;
ãã®ä¾ã§ã¯ãxã¨ããå¤æ°ã宣è¨ãã¦ããã®å¤æ°ã®å¤ã§åæåãã¦ããããã®ã³ã¼ãã«å®ç¨çãªæå³ã¯ãªããåæååã®ä¸ããã宣è¨ãããååã¯ä½¿ããã¨ãããã¨ã示ãããã ãã®ä¾ã§ããã
// ã¨ã©ã¼
int x[x /*ããã§ã¯ãã¾ã xã¯æªå®ç¾©*/ ] ;
ãã®ä¾ã¯ãã¨ã©ã¼ã§ããããªããªããé
åã®è¦ç´ æ°ãæå®ããå ´æã§ã¯ãxã¯ãã¾ã å®ç¾©ããã¦ããªãããã ããããã®ä¾ã¯ãé常ã¯æ°ã«ãããã¨ã¯ãªããäºç´°ãªè©³ç´°ã§ãããä¸è¬ã«ã宣è¨æã®ããå¾ãã使ããã¨èãã¦ããã°ããã
ãããã¯ã®ã¹ã³ã¼ãã¯ããã®ãããã¯ã®ä¸ã§ããããããããããã¯ã¹ã³ã¼ãã¨å¼ã¶ãããããã¼ã«ã«å¤æ°ã¨å¼ãã§ãããã®ã¯ããããã¯ã¹ã³ã¼ãã®ä¸ã§å®£è¨ãããå¤æ°ã®ãã¨ã§ããã
void f()
{ // ãããã¯1
int x ;
{ // ãããã¯2
int y ;
{ // ãããã¯3
int z ;
// x, y, zã使ãã
}
// x, yã使ããã
}
// xã使ããã
}
// ããã§ä½¿ããå¤æ°åã¯ãªãã
ãããã¯ã¯ãã¹ãã§ããã®ã§ããã¹ãããããããã¯ã®ä¸ã§ãå¤å´ã®ã¹ã³ã¼ãã¨åãååã®å¤æ°ã使ãããå ´åã¯ã注æãå¿
è¦ã§ããã
void f()
{
int x ;
{
int x ; // å¤å´ã®ã¹ã³ã¼ãã®xã¯é ãããã
}
}
é¢æ°ã®ä»®å¼æ°åã¯ãé¢æ°æ¬ä½ã®ä¸çªä¸ã®ãããã¯ã¹ã³ã¼ãã®çµããã¾ã§ãæå¹ã§ããã
void f( int x )
{
// xã¯ããã¾ã§æå¹
}
// ãã以éãxã¯ä½¿ããªãã
é¢æ°ã®ãããã¿ã¤ã宣è¨ã«ããã¹ã³ã¼ãããããé¢æ°ã®ãããã¿ã¤ã宣è¨ã®ã¹ã³ã¼ãã¯ããã®å®£è¨ã®çµããã¾ã§ã§ããã
auto f( int x ) -> decltype(x) ;
ãã®ä¾ã§ã¯ãä»®å¼æ°ã®ååããdecltypeã«ä½¿ããã¦ããã
ãããã¯ã¹ã³ã¼ãã§ã¯ãªããé¢æ°èªä½ã«ããé¢æ°ã®ã¹ã³ã¼ããåå¨ãããããã¯ãããé¢æ°å
¨ä½ã®ã¹ã³ã¼ãã§ããããã ãããã®é¢æ°ã®ã¹ã³ã¼ããé©ç¨ãããã®ã¯ãã©ãã«åã ãã§ããã
void f()
{
{
label : ;
}
goto label ; // labelã¯ãããã§ãæå¹
}
ãã®ããã«ãã©ãã«åã«ã¯ãé¢æ°ã®ã¹ã³ã¼ããé©ç¨ãããã
åå空éã®ã¹ã³ã¼ãã¨ããã®ã¯ãå°ãããããããã¾ããåå空éã®æ¬ä½ã¯ããã¡ããã¹ã³ã¼ãã§ããã
namespace NS
{
int x ;
// xã使ããã
}
// ããã§ã¯ãxã¯ä½¿ããªãã
ãã®ãåå空éã®ä¸ã®ååï¼ä¸ã®ä¾ã§ã¯ãxï¼ããåå空éã®ã¡ã³ãã¼åã¨ãããã¡ã³ãã¼åã®ã¹ã³ã¼ãã¯ãåå空éã®çµããã¾ã§ã§ããã
ã¨ããããåå空éã®æ¬ä½ã®å®ç¾©ã¯ãè¤æ°æ¸ããã¨ãã§ããã
namespace NS
{
int x ;
// xã使ããã
}
// ããã§ã¯ãxã¯ä½¿ããªãã
namespace NS
{
// ããã§ããxã使ããã
int y = x ;
}
ã¡ã³ãã¼åã¯ããã®å®£è¨ãããå ´æãããå¾ç¶ãããã¹ã¦ã®ååã®åå空éã®ä¸ã§ä½¿ããã¨ãã§ããããã®ä¾ã®å ´åãäºã¤ãã®åå空éNSã®å®ç¾©ã®ä¸ã§ããä¸ã¤ãã®åå空éNSã®å®ç¾©ã§å®£è¨ãããã¡ã³ãã¼åã§ãããxã使ããã¨ãã§ããã
åå空éã®ã¡ã³ãã¼ã¯ãã¹ã³ã¼ã解決æ¼ç®åã::ã使ã£ã¦ãåç
§ãããã¨ãã§ããã
namespace NS
{
using type = int ;
}
// åå空éNSã®ãtypeã¨ããååãåç
§ãã¦ããã
NS::type x ;
翻訳åä½ã®ãä¸çªä¸ã®ãnamespaceã§å²ã¾ãã¦ããªãå ´æããä¸ç¨®ã®åå空éã¨ãã¦æ±ããããããã¯ãã°ãã¼ãã«åå空éã¨å¼ã°ãã¦ãããã°ãã¼ãã«åå空éã§å®ç¾©ãããååã¯ãã°ãã¼ãã«åå空éã®ã¹ã³ã¼ãã«å
¥ããããã¯ãã°ãã¼ãã«ã¹ã³ã¼ãã¨ãå¼ã°ãã¦ãããã°ãã¼ãã«åå空éã®ã¹ã³ã¼ãã¯ã翻訳åä½ã®çµããã¾ã§ã§ããã
// ã°ãã¼ãã«åå空é
int x ;
namespace NS
{ // åå空éãNS
}
// ããã¯ãã°ãã¼ãã«åå空é
namespace
{ // ç¡ååå空é
}
// ããããã°ãã¼ãã«åå空é
// xã®ç¯å²ã¯ã翻訳åä½ã®çµããã¾ã§ç¶ãã
ã¯ã©ã¹ã®ã¹ã³ã¼ãã¯ãå°ãå¤ãã£ã¦ããããããã¯ã¹ã³ã¼ããªã©ã¯ãååã®æå¹ãªç¯å²ã¯ãååã宣è¨ããå ´æãããã¹ã³ã¼ãã®çµããã¾ã§ã§ããã
void f()
{
// ããã§ã¯ãxã¯ä½¿ããªãã
int x ; // xã宣è¨
// ããã§ã¯ãxã使ããã
}
ã¯ã©ã¹ã§ã¯ããããå¤ãã£ã¦ããã
å
ã«ãååã宣è¨ããã¦ããªãã¦ããã¯ã©ã¹å
ã®é¢æ°ããã¯ããã®ååã使ããã¨ãã§ããã
class C
{
void f()
{ // é¢æ°ã®ä¸ã§ãååã使ããã¨ãã§ããã
type x ;
value = 0 ;
}
type y ; // ã¨ã©ã¼ãtypeã¯å®£è¨ããã¦ããªãã
using type = int ; // typeã®å®£è¨å ´æ
type z ; // OK
int value ; // valueã®å®£è¨å ´æ
} ;
ã¾ããã¯ã©ã¹ã®ã¡ã³ãã¼é¢æ°ããã¯ã©ã¹ã®å¤é¨ã§å®ç¾©ããå ´åã§ãããã®é¢æ°ã®ä¸ãããã¯ã©ã¹å
ã§å®£è¨ãããååã使ããã¨ãã§ããã
class C
{
void f() ;
int x ;
} ;
void C::f()
{ // ã¯ã©ã¹å¤é¨ã§å®ç¾©ãããã¡ã³ãã¼é¢æ°ã®ä¸ã§ãã¯ã©ã¹å
ã§å®£è¨ãããååã使ããã
x = 0 ;
}
ãã®ä»ã«ããã¯ã©ã¹å
ã®ååããã¯ã©ã¹å¤ã§ä½¿ããã¨ãã§ããå ´åãåå¨ããã
class C
{
public :
int x ;
using type = int ;
} ;
int main()
{
C c ;
C * p = &c ;
// ã¯ã©ã¹ã®ã¡ã³ãã¼ã¢ã¯ã»ã¹æ¼ç®åã®å¾ã«ç¶ãã¦ãååã使ããã
c.x = 0 ;
p->x = 0 ;
// ã¹ã³ã¼ã解決æ¼ç®åã®å¾ã«ç¶ãã¦ãååã使ããã
C::type value ;
}
ãã®ããã«ãã¯ã©ã¹ã¹ã³ã¼ãã®ååã¯ã宣è¨ããå ´æãããããåºéã¾ã§æå¹ã¨ããã«ã¼ã«ã§ã¯ãªãããã®ãããã¯ã©ã¹ã®ã¹ã³ã¼ãã«ã¯ç¹å¥ãªã«ã¼ã«ãããã
- ã¯ã©ã¹ã®ã¡ã³ãã¼ã®å®£è¨ãå
¨ã¦ããã£ããã¨ã«ãã¯ã©ã¹å®£è¨ãåè©ä¾¡ãã¦ãããã°ã©ã ã®æå³ãå¤ããã¨ã¨ã©ã¼
- ã¯ã©ã¹å
ã®ã¡ã³ãã¼ã®å®£è¨ã®é çªãå¤ããéã«ãããã°ã©ã ã®æå³ãå¤ããã¨ãã¨ã©ã¼
ããã¯ãä¾ãããã¦èª¬æããã»ããåããããããä»ä»®ã«ããã®ã«ã¼ã«ããªããã®ã¨ãããã¨ããã¨ã以ä¸ã®ãããªã³ã¼ããæ¸ãã¦ãã¾ãã
// ã³ã¼ã1
using type = int ; // #1
class C
{
type x ; // ãã®typeã¯ã#1ã®::type
using type = float ; // #2
} ;
ã¯ã©ã¹Cã®å®£è¨ã®é çªãå¤ããã¨ã以ä¸ã®ã³ã¼ãã«ãªãã
// ã³ã¼ã2
using type = int ; // #1
class C
{
using type = float ; // #2
type x ; // ãã®typeã¯ã#2ã®ãC::type
} ;
ãã®ããã«ãã¡ã³ãã¼ã®å®£è¨ã®é çªãå¤ãããã¨ã«ãã£ã¦ãããã°ã©ã ã®æå³ãå¤ãã£ã¦ãã¾ãã¨ãæå³ãã¬ãã°ãçãåå ã¨ãªãããã®ããããã®ãããªã³ã¼ãã¯ãã¨ã©ã¼ã§ããã
scoped enumã¯ãenumã¹ã³ã¼ãï¼enumeration scopeï¼ãæã¤ããã®ã¹ã³ã¼ãã®ç¯å²ã¯ãenumã®å®£è¨å
ã ãã§ããã
enum class E { x, y, z } ;
// ããã§ãx, y, zã¯ä½¿ããªãã
x ; // ã¨ã©ã¼
E::x ; // OK
ãã®çç±ã¯ãscoped enumã¯ãå¼·ãåä»ããæã¤enumã ããã ã詳ããã¯ãenumãåç
§ã®ãã¨ã
ãã³ãã¬ã¼ãä»®å¼æ°ã«ããã¹ã³ã¼ããããããã³ãã¬ã¼ãä»®å¼æ°ã®ã¹ã³ã¼ãã¯ãããã»ã©æèããå¿
è¦ã¯ãªãã
template <
typename T, // ãã以éãTã使ããã
typename U = T >
class C { } ; // ãã³ãã¬ã¼ãä»®å¼æ°ã®ã¹ã³ã¼ããããã¾ã§
ãã ãããã³ãã¬ã¼ãä»®å¼æ°åã¯ãåºæ¬çã«ãé ããã¨ãã§ããªãã
template < typename T >
class C
{
using T = int ; // ã¨ã©ã¼
// ã¨ã©ã¼
template < typename T >
void f() ;
} ;
ãåºæ¬çã«ãã¨ããã®ã¯ãé ããã¨ãã§ããå ´åãåå¨ããããã ã
struct Base{ using T = type ; } ;
template < typename T >
struct Derived : Base
{
T x ; // Base::Tã使ãããããã³ãã¬ã¼ãä»®å¼æ°ã§ã¯ãªãã
} ;
ã¨ãã£ã¦ããããã¯ãã»ã©ç¹æ®ãªä¾ã§ãããé常ã¯ããã³ãã¬ã¼ãä»®å¼æ°åã¯ãé ããªãã¨èãã¦ããåé¡ã¯ãªãã
ãã¹ããããã¹ã³ã¼ãã®å
å´ã§ãåãååã宣è¨ãããã¨ãå¤å´ã®ååã¯ãé ãããã
void f()
{ // å¤å´ã®ã¹ã³ã¼ã
int x ;
{ // å
å´ã®ã¹ã³ã¼ã
int x ; // å¤å´ã®ã¹ã³ã¼ãã®xãé ãã
x = 0 ; // å
å´ã®x
}
x = 0 ; // å¤å´ã®x
}
æ´¾çã¯ã©ã¹ã§ã¯ãåºæ¬ã¯ã©ã¹ã®ååã¯é ãããã
struct Base { using type = char ; } ;
struct Derived : Base
{
using type = int ;
type x ; // int
} ;
ã¯ã©ã¹ãenumã®ååã¯ãå¤æ°ããã¼ã¿ã¡ã³ãã¼ã®ååã«ãã£ã¦ãé ãããã
class ClassName {} ;
void f()
{
ClassName ClassName ; // OKãClassNameåã®å¤æ°ãClassName
ClassName x ; // ã¨ã©ã¼ãClassNameã¯ãããã§ã¯å¤æ°åãæãã
class ClassName x ; // OKãæ示çã«ã¯ã©ã¹åã§ããã¨æå®ãã¦ããã
}
ãã®ããã«ãã¯ã©ã¹åã¨å¤æ°åãåãã«ããã®ã¯ãé常ã«åããã«ããåé¡ãå¼ãèµ·ããã®ã§ããã¾ãããããã§ããªãã
ããã¹ã³ã¼ãã«ããã¦ãããååã使ããã¦ããã¨ãããã®ååãä½ãæå³ããã®ãã¨ãããã¨ã決å®ããã®ããååæ¢ç´¢ï¼Name lookupï¼ã¨å¼ã¶ãããã¯ä¸è¦ç°¡åããã«æããããããããã®ååã決å®ããã¨ããã«ã¼ã«ã¯ãé常ã«é£ããã
Name lookupã«ã¯ã大ããåãã¦ãä¸ç¨®é¡ãããQualified name lookupãUnqualified name lookupãArgument-dependent name lookupã ã
Qualified nameã¨ã¯ãqualifiedï¼ä¿®é£¾ï¼ã¨ããååéããã¹ã³ã¼ã解決æ¼ç®åï¼::ï¼ã使ã£ãååã®ãã¨ã§ããã
int g ;
namespace NS { int x ; }
struct C { static int x ; } ;
int C::x ;
enum struct E { e } ;
int main()
{
// ãããã¯Qualified name lookup
NS::x ; // NSã¨ããåå空éã®x
C::x ; // Cã¨ããã¯ã©ã¹ã®x
E::e ; // Eã¨ããenumã®ã¡ã³ãã¼ãe
::g ; // ã°ãã¼ãã«åå空éã®g
}
ãã®ãããªååã«å¯¾ããååæ¢ç´¢ããQualified name lookupã¨ããã
ã¹ã³ã¼ã解決æ¼ç®åï¼::ï¼ã®å·¦å´ã«ã¯ãã¯ã©ã¹åããåå空éåããenumåãæ¸ããã¨ãã§ãããå·¦å´ã«ä½ãæ¸ããªãå ´åãã°ãã¼ãã«åå空éã使ããããQualified name lookupã§ã¯ãååã¯ãã¹ã³ã¼ã解決æ¼ç®åã§æå®ããããã¯ã©ã¹ãåå空éãenumå
ã®ååãããæ¢ç´¢ãããã
ã¹ã³ã¼ã解決æ¼ç®åã¯ããã¹ãã§ããã
namespace N1 { namespace N2 {
int x ;
} }
N1::N2::x ;
Unqualifiedï¼éä¿®é£¾ï¼ name lookupã¯ãQualified name lookup以å¤ãæããããã¯ã¤ã¾ããã¹ã³ã¼ã解決æ¼ç®åã使ããªãååã«å¯¾ãããååæ¢ç´¢ã§ããã
int g ;
namespace NS { int x ; }
int main()
{
g ; // ã°ãã¼ãã«å¤æ°ã®g
int g ;
g ; // ãã¼ã«ã«å¤æ°ã®g
{
using namespace NS ;
x ; // NS::xã¨åã
}
{
using NS::x ;
x ; // NS::xã¨åã
}
}
Unqualified nameã«å¯¾ããååæ¢ç´¢ããUnqualified name lookupã¨ãããUnqualified name lookupã§ã¯ããã®ååã使ããã¦ããå ´æã§ãæ示çã«ä¿®é£¾ããªãã¦ããè¦ã¤ããååãæ¢ããããããã¯ãä¾ãã°ã°ãã¼ãã«åå空éå
ã®ååã§ãã£ãããã¯ã©ã¹å
ã§ããã°ãã¯ã©ã¹ã®ã¡ã³ãã¼ã§ãã£ãããããã¾ããusing directiveããusing declarationã®å½±é¿ããããã
Unqualified nameã«å¯¾ãã¦ãé¢æ°å¼ã³åºããããå ´åãç¹å¥ãªã«ã¼ã«ãããããã®ã«ã¼ã«ããADL(Argument-dependent name lookup)ã¨ããã
namespace NS
{
class C {} ;
void f( C ) {}
}
int main()
{
NS::C c ;
f(c) ; // NS::fãå¼ã¶
}
ãã®ã³ã¼ãã§ã¯ãé常ã¯è¦ã¤ãããªãã¯ãã®ãNSã¨ããåå空éå
ã®é¢æ°ã§ããfããUnqualified nameãªã®ã«ãããããããè¦ã¤ãããããããå®å¼æ°ã«ä¾åããååæ¢ç´¢ï¼Argument-dependent name lookupï¼ã¨å¼ã¶ããã°ãã°ãADLã¨ç¥ããããã¾ããAndrew Koenigããããåå空éã®å°å
¥ã«ãã£ã¦ãç¹ã«æ¼ç®åã®ãªã¼ãã¼ãã¼ãã§ãADLã®ãããªå¿
è¦æ§ãæè¦ãããããKoenig lookupã¨ãå¼ã°ãããã¨ããããAndrew KoenigããããADLã®å
·ä½çãªä»çµã¿ãèæ¡ããããã§ã¯ãªãã誰ãADLã®åæ¡ãèãã ããã®ãã¯ãæ´å²ã«åããã¦å¿ãå»ããã¦ãããããã®ãããªæ´å²çãªçµç·¯ã¨èª¤è§£ã«ãããKoenig lookupã¨å¼ã°ãã¦ããã
ãã®ADLã¨ããã«ã¼ã«ã¯ãä¸è¦ããã¨ãé常ã«å¥å¦ãªã«ã¼ã«ã§ããããã®ãããªä»çµã¿ã¯ãé常ã«åä»ãªåé¡ãå¼ãèµ·ããã®ã§ã¯ãªãããäºå®ãADLã¯æã¨ãã¦ãåé¡ã«ãªããã¨ããããããã§ãADLãåå¨ããã®ã¯ãå©ç¹ãããããã ã
æ´æ°ã表ç¾ããã¯ã©ã¹ãIntegerãèãããååã®è¡çªãé²ãããããã®ã¯ã©ã¹ã¯ãlibã¨ããåå空éã®ä¸ã«å
¥ããããã¾ããæ´æ°ã¨ãã¦åããããã使ãããã«ãæ¼ç®åããªã¼ãã¼ãã¼ãããããIntegerã¯ã©ã¹ã¯ã以ä¸ã®ããã«ä½¿ãããã®ã¨ããã
int main()
{
lib::Integer x ;
// æ¼ç®åã®ãªã¼ãã¼ãã¼ãã«ãããåãããããå ç®ã®ã³ã¼ãã
x + x ;
}
ãã£ããããã®Integerãå®è£
ãã¦ã¿ããã
namespace lib
{
// ã¯ã©ã¹
class Integer { /*å®è£
*/ } ;
// æ¼ç®åã®ãªã¼ãã¼ãã¼ã
Integer operator + ( Integer const &, Integer const &)
{
// å®è£
return Integer() ;
}
}
ããããã§ãADLããªãå ´åãoperator +()ã®å¼ã³åºãããå°ã£ããã¨ã«ãªãããªããªããUnqualified lookupã§ã¯ãlibåå空éã®ä¸ã®ååãæ¢ãã¦ã¯ãããªããã¤ã¾ããoperator +ã¯ãè¦ã¤ãããªãã®ã§ããã
lib::Integer x ;
// ã¨ã©ã¼ãoperator + ãè¦ã¤ãããªãã
x + x ;
ã§ã¯ã©ãããããããã¯ãQualified lookupã使ããããªãã
lib::operator +( x, x ) ;
ãã®ã³ã¼ãã¯åãã確ãã«åãããããã§ã¯ããã£ããæ¼ç®åããªã¼ãã¼ãã¼ãããæå³ããªãããããããæ¼ç®åããªã¼ãã¼ãã¼ãããçç±ã¨ã¯ãx + x ã¨ãããåããããã使ãæ
£ããã³ã¼ããæ¸ãããã ããã ã
ãã®ãããUnqualified nameã«å¯¾ãããé¢æ°å¼ã³åºãã«ã¯ãUnqualified name lookupã«å ãã¦ãADLã¨ããä»çµã¿ã§ãååãæ¢ç´¢ãããããã«ãªã£ã¦ããã
ADLã¯ããã®ååã示ãã¨ããããå®å¼æ°ã«ä¾åããåå解決ãã§ãããã©ã®åå空éãããååãæ¢ããã¨ãããã¨ã¯ãå®å¼æ°ã®åãã決å®ããããã¾ããADLã¯ãå¿
ãè¡ãããããã§ã¯ãªããADLãé©ç¨ãããæ¡ä»¶ã¨ãããã®ãåå¨ããã
ADLã¯ã©ã®ããã«è¡ãããããã¾ããé¢æ°ã«å¯¾ãããé¢é£ã¯ã©ã¹ï¼Associated classï¼ã¨ãé¢é£åå空éï¼Associated namespaceï¼ã¨ãããã®ã決å®ããããADLã¯ããã®é¢é£åå空éã®ä¸ãããååãæ¢ç´¢ããã
é¢é£ã¯ã©ã¹ã¨ã¯ãé¢æ°ã«å®å¼æ°ã¨ãã¦æ¸¡ãããåã§ãããé¢é£åå空éã¨ã¯ãé¢é£ã¯ã©ã¹ãã¡ã³ãã¼ã¨ãªã£ã¦ããåå空éã§ããã
namespace NS
{
class A {} ; class B {} ; class C {} ; class D {} ;
void f( A, B, C, D ) {}
}
int main()
{
NS::A a ; NS::B b ; NS::C c ; NS::D d ;
f( a, b, c, d ) ;
}
ãã®å ´åãfã®é¢æ°å¼ã³åºãã«å¯¾ããé¢é£ã¯ã©ã¹ã¯ãAãBãCãDã§ãé¢é£åå空éã¯ãNSã¨ãªãã
namespace A { class C {} ; }
namespace B
{
class C {} ;
void f( A::C, B::C ) {}
}
int main()
{
A::C ac ; B::C bc ;
f( ac, bc ) ;
}
ãã®å ´åãfã®é¢æ°å¼ã³åºãã«å¯¾ããé¢é£ã¯ã©ã¹ã¯ãA::CãB::Cã§ãé¢é£åå空éã¯ãAãBã¨ãªãã
å®å¼æ°ã®åã®ã¯ã©ã¹ã®ãåºæ¬ã¯ã©ã¹ããé¢é£ã¯ã©ã¹ã«ãªãã
namespace NS
{
class A {} ;
class B : A {} ;
class C : B {} ;
void f( C ) {}
}
int main()
{
NS::C c ;
f( c ) ;
}
ãã®å ´åãé¢æ°NS::fã«å¯¾ããé¢é£ã¯ã©ã¹ã¯ãAãBãCã§ãé¢é£åå空éã¯ãNSã¨ãªãã
å®å¼æ°ãã¯ã©ã¹ãã³ãã¬ã¼ãã§ãã£ãå ´åããã®ã¯ã©ã¹ã®ãã³ãã¬ã¼ãå®å¼æ°ããé¢é£ã¯ã©ã¹ã«ãªãã
namespace NS
{
template < typename T > class C {} ;
}
namespace lib
{
class type {} ;
template < typename T >
void f( NS::C<T> ) {}
}
int main()
{
NS::C< lib::type > c ;
// é¢é£ã¯ã©ã¹ã¯ãNS::C< lib::type >ã¨ãlib::typeã
// é¢é£åå空éã¯ãNSã¨ãlibã
f(c) ; // lib::fãå¼ã³åºãã
}
ãã³ãã¬ã¼ãå®å¼æ°ãé¢é£ã¯ã©ã¹ã«ãªãã¨ããã«ã¼ã«ã¯ããã®ä¾ã®ãããªãé常ã«åããã«ããã³ã¼ãã®ã³ã³ãã¤ã«ãéãã¦ãã¾ãã
å®å¼æ°ãã¯ã©ã¹ä»¥å¤ã®å ´åããADLã¯é©ç¨ãããã
å®å¼æ°ãenumã®å ´åããã®enumãå®ç¾©ããã¦ããåå空éããé¢é£åå空éã«ãªãã
namespace NS
{
enum struct E { value } ;
void f( E ) {}
}
int main()
{
f( NS::E::value ) ; // NS::fãå¼ã³åºãã
}
ãã®å ´åãé¢æ°ãNS::fã®é¢é£åå空éã¯ãNSã¨ãªãã
ADLãé©ç¨ãããã«ã¯ãæ¡ä»¶ãæºãããªããã°ãªããªããã¾ããADLã¯ãUnqualified nameã¸ã®é¢æ°å¼ã³åºãã«ãããé©ç¨ãããªããå¤æ°ã¨ãã¦ã®ä½¿ç¨ã«ã¯ãADLã¯ä½¿ãããªãã
namespace NS
{
class C {} ;
void f( C ) {}
void g( C ) {}
}
void g( NS::C ) {}
int main()
{
NS::C c ;
f(c) ; // ADLã§ãNS::fãå¼ã¶
NS::f(c) ; // Qualified name lookupãè¡ããã
::g(c) ; // Qualified name lookupãè¡ããã
NS::g(c) ; // Qualified name lookupãè¡ããã
g(c) ; // ã¨ã©ã¼ã::gãNS::gã®ã©ã¡ãã®ååããææ§ã
}
æå¾ã®ä¾ã¯ãUnqualified name lookupã§ã::gãçºè¦ãããADLã§ãNS::gãçºè¦ãããã®ã§ãã©ã¡ãã®ååã使ãã®ããææ§ã§ãã¨ã©ã¼ã«ãªãã
ãããUnqualified name lookupã§ãé¢æ°å以å¤ã®ååãè¦ã¤ãã£ãå ´åãADLã¯è¡ãããªãã
namespace NS
{
class C {} ;
void f( C ) {}
}
int f ;
struct Caller
{
void f( NS::C ) {}
void g()
{
NS::C c ;
f(c) ; // Caller::fãå¼ã°ãããADLã¯è¡ãããªãã
}
} ;
int main()
{
NS::C c ;
f(c) ; // ã¨ã©ã¼ãfã¯intåã®å¤æ°
}
ãããã¯ã¹ã³ã¼ãé¢æ°å®£è¨ã®ååãè¦ã¤ãã£ãå ´åãADLã¯è¡ãããªãããã ããusing宣è¨ããusingãã£ã¬ã¯ãã£ãã¯ãå½±é¿ããªãã
namespace NS
{
class C {} ;
void f( C ) {}
}
namespace lib { void f( NS::C ) {} }
int main()
{
NS::C c ;
{
void f( NS::C ) ; // ãããã¯ã¹ã³ã¼ãã®é¢æ°å®£è¨
f(c) ; // ::fãå¼ã³åºãããããã¯ã¹ã³ã¼ãã®å®£è¨ãè¦ã¤ãã£ãã®ã§ãADLã¯è¡ãããªãã
}
{
using namespace lib ;
f(c) ; // ã¨ã©ã¼ãADLãè¡ãããã®ã§ãææ§ã«ãªãã
}
{
using lib::f ;
f(c) ; // ã¨ã©ã¼ãADLãè¡ãããã®ã§ãææ§ã«ãªãã
}
}
// ãããã¯ã¹ã³ã¼ãã®é¢æ°å®£è¨ã§åç
§ããããã°ãã¼ãã«åå空éã®f
void f( NS::C ) {}
ãããã¯ã¹ã³ã¼ãå
ã§é¢æ°å®£è¨ãããã¨ãããã¨ã¯ãè¨èªä¸ã¯èªãããã¦ããããç¾å®çã«ã¯ããã¾ãç¨ãããã¦ããªãã
using宣è¨ããusingãã£ã¬ã¯ãã£ãããADLã®é©ç¨ã妨ããªãã¨ãããã¨ã¯ã注æãè¦ãããããã«ãããä¸æè°ãªã³ã³ãã¤ã«ã¨ã©ã¼ã«ãªããã¨ããããä¾ãã°ãä¸ã®ä¾ã®å ´åãNSåå空éã®ã³ã¼ãã¯ãä»äººãæ¸ãããã®ã§ãããã¦ã¼ã¶ã¼ã¯ããç¥ããªãã¨ããããlibåå空éã®ã³ã¼ãã¯ãã¦ã¼ã¶ã¼ãæ¸ãããã®ã§ãããã¦ã¼ã¶ã¼ã¯ãlib::fã使ããããmainé¢æ°å
ã§å¤ç¨ããã®ã§ãusing宣è¨ã使ã£ã¦ãç°¡åã«å¼ã³åºããããã«ãããã¨ããããNSåå空éã®ä¸ã«ããååã®é¢æ°ãããã®ã§ãææ§ã¨ã©ã¼ã«ãªã£ã¦ãã¾ãã
ADLãæå³ããé©ç¨ãããéã®ã¨ã©ã¼ã¯ãé常ã«åããã«ããããã®ãããADLãé²ãããã®æ¹æ³ãç¨æããã¦ãããååãæ¬å¼§ã§å²ãã°ãADLã®é©ç¨ãé»å®³ãããã
namespace NS
{
class C {} ;
void f( C ) {}
}
void f( NS::C ) {}
int main()
{
NS::C c ;
f(c) ; // ã¨ã©ã¼ãææ§
(f)(c) ; // OKãADLã¯é©ç¨ãããªãã::fãå¼ã³åºãã
}
unqualified nameã¸ã®é¢æ°å¼ã³åºãã¯ãé常ã®unqualified name lookupã¨ãADLã¨ã§è¦ã¤ãã£ãååã®ã両æ¹ãç¨ããããã
C++ã«ããã¦ãããã°ã©ã (program)ã¨ã¯ãã²ã¨ã¤ä»¥ä¸ã®ç¿»è¨³åä½(translation unit)ãçµã¿åããã£ããã®ã§ããã翻訳åä½ã¨ããã®ã¯ãä¸é£ã®å®£è¨ã§æ§æããã¦ããã
ããããC++ã®å®è£
ã¨ãã¦ã¯ã翻訳åä½ã¯ãã½ã¼ã¹ãã¡ã¤ã«ã¨ããåä½ã§åãããã¦ããã
åããªãã¸ã§ã¯ãããªãã¡ã¬ã³ã¹ãé¢æ°ãåããã³ãã¬ã¼ããåå空éãå¤ãæã示ãååãã宣è¨ã«ãã£ã¦å¥ã®ã¹ã³ã¼ãã«å°å
¥ãããæããã®ååã¯ãªã³ã±ã¼ã¸(linkage)ãæã¤ã
-
ååãå¤é¨ãªã³ã±ã¼ã¸(external linkage)ãæã¤å ´åããã®ååãæã示ãã¨ã³ãã£ãã£ã¯ãä»ã®ç¿»è¨³åä½ã®ä»»æã®ã¹ã³ã¼ãã®ä¸ããåã翻訳åä½ã®å¥ã®ã¹ã³ã¼ãã®ä¸ããåç
§ã§ããã
-
ååãå
é¨ãªã³ã±ã¼ã¸(internal linkage)ãæã¤å ´åããã®ååãæã示ãã¨ã³ãã£ãã£ã¯ãåã翻訳åä½ã®å¥ã®ã¹ã³ã¼ãããåç
§ã§ãããã¤ã¾ããå¥ã®ç¿»è¨³åä½ããã¯åç
§ã§ããªãã¨ãããã¨ãæå³ããã
ååããªã³ã±ã¼ã¸ãæããªãå ´åããã®ååãæã示ãã¨ã³ãã£ãã£ã¯ãä»ã®ã¹ã³ã¼ãããåç
§ã§ããªãã
ããååããªã³ã±ã¼ã¸ãæã¤ã®ãæããªãã®ãããªã³ã±ã¼ã¸ãæã¤å ´åãå¤é¨ãªã³ã±ã¼ã¸ãªã®ãå
é¨ãªã³ã±ã¼ã¸ãªã®ãã¨ããã«ã¼ã«ã¯è¤éã§ããã
åºæ¬çãªèãæ¹ã¨ãã¦ã¯ãã°ãã¼ãã«åå空éãå«ãåå空éã¹ã³ã¼ãã®ååã¯ãã»ã¨ãã©ãå¤é¨ãªã³ã±ã¼ã¸ãæã¤ãå
é¨ãªã³ã±ã¼ã¸ãæã¤ãã®ã¯ã大æµãæ示çãªæå®åãä¼´ãããªã³ã±ã¼ã¸ãæããªãã¨ã³ãã£ãã£ã¯ãããããååãæããªãå ´åãå¤ãã
åå空éã¹ã³ã¼ãã®ååã§ãå
é¨ãªã³ã±ã¼ã¸ãæã¤ãã®ã¯ã以ä¸ã®éãã
-
æ示çã«staticã¨å®£è¨ããã¦ããå¤æ°ãé¢æ°ãé¢æ°ãã³ãã¬ã¼ã
static int x ;
static void f() { }
template < typename T >
static void f() { }
-
æ示çã«constãconstexprã¨å®£è¨ããã¦ãã¦ãæ示çã«externã¨å®£è¨ããã¦ããããåæ¹ã§å¤é¨ãªã³ã±ã¼ã¸ããã¤ã¨å®£è¨ããã¦ãããªããã®
const int x = 0 ;
constexpr int y = 0 ;
-
ç¡åunionã®ãã¼ã¿ã¡ã³ãã¼
static union { int x ; } ;
ç¡ååå空éããç¡ååå空éå
ã§ãç´æ¥çãéæ¥çã«å®£è¨ãããåå空éã¯ãå
é¨ãªã³ã±ã¼ã¸ãæã¤ã
// ãã®ç¡ååå空éã¯å
é¨ãªã³ã±ã¼ã¸ãæã¤
namespace { }
namespace
{
// åå空éinternalã¯å
é¨ãªã³ã±ã¼ã¸ãæã¤
namespace internal
{
// åå空éindirectã¯å
é¨ãªã³ã±ã¼ã¸ãæã¤
namespace indirect { }
}
}
ãã以å¤ã®åå空éã¯ããã¹ã¦å¤é¨ãªã³ã±ã¼ã¸ãæã¤ãä¾ãã°ãã°ãã¼ãã«åå空éãå¤é¨ãªã³ã±ã¼ã¸ãæã¤ã
åå空éã¹ã³ã¼ããæã¤ã次ã«æãã種é¡ã®ååã¯ãã¹ã¦ãå±ããåå空éã¹ã³ã¼ãã¨åããªã³ã±ã¼ã¸ãæã¤ã
-
å¤æ°
-
é¢æ°
-
ååã®ããã¯ã©ã¹ããããã¯ãtypedef宣è¨ã«ãã£ã¦å®ç¾©ãããç¡åã¯ã©ã¹ã§ãtypedefåããã¤ã¯ã©ã¹
// ã°ãã¼ãã«åå空é
// å¤é¨ãªã³ã±ã¼ã¸ãæã¤
struct Named { } ;
// å¤é¨ãªã³ã±ã¼ã¸ãæã¤
typedef struct { } Typedef_named ;
-
ååã®ããenumããããã¯ãtypedef宣è¨ã«ãã£ã¦å®ç¾©ãããç¡åenumã§ãtypedefåããã¤ãã®
-
åæåã¯ããã®å±ããenumã®ãªã³ã±ã¼ã¸ã«å¾ã
// fooã®ãªã³ã±ã¼ã¸ã¯Eã®ãªã³ã±ã¼ã¸ã¨åã
enum E { foo } ;
-
ãã³ãã¬ã¼ã
ã¤ã¾ããåå空éã®ãªã³ã±ã¼ã¸ã«å¾ãã
// ã°ãã¼ãã«åå空é
namespace ns
{
int foo ; // å¤é¨ãªã³ã±ã¼ã¸
}
namespace
{
int bar ; // å
é¨ãªã³ã±ã¼ã¸
}
ã¡ã³ãã¼é¢æ°ãstaticãã¼ã¿ã¡ã³ãã¼ãã¯ã©ã¹ã¹ã³ã¼ãã®ååã®ããã¯ã©ã¹ãenumãã¯ã©ã¹ã¹ã³ã¼ãã®typedef宣è¨ã§å®ç¾©ãããç¡åã¯ã©ã¹ãç¡åenumã§typedefåããã¤ãã®ã¯ããã®å±ããã¯ã©ã¹ãå¤é¨ãªã³ã±ã¼ã¸ãæã¤å ´åãå¤é¨ãªã³ã±ã¼ã¸ãæã¤ã
ãããã¯ã¹ã³ã¼ãã§å®ç¾©ããããé¢æ°åã¨ãextern宣è¨ãããå¤æ°åã¯ããªã³ã±ã¼ã¸ãæã¤ã
void f()
{
extern void g() ; // ãªã³ã±ã¼ã¸ãæã¤
extern int global ; // ãªã³ã±ã¼ã¸ãæã¤
g() ; // OK
global = 123 ; // OK
}
// å¥ã®ç¿»è¨³åä½
void g() { }
int global ;
ããããããã¯ã¹ã³ã¼ãã®å¤ã®ç´åã®åå空éã¹ã³ã¼ãã§ãåãååãåãã¨ã³ãã£ãã£ã§ãªã³ã±ã¼ã¸ã ããéãåæ¹å®£è¨ããªããã¦ããå ´åããããã¯ã¹ã³ã¼ãã®ãªã³ã±ã¼ã¸æå®ã¯ç¡è¦ãããåæ¹å®£è¨ã®ãªã³ã±ã¼ã¸ã使ãããã
// ã°ãã¼ãã«åå空é
static void f(); // å
é¨ãªã³ã±ã¼ã¸
static int i = 0; // å
é¨ãªã³ã±ã¼ã¸
void g() {
extern void f(); // å
é¨ãªã³ã±ã¼ã¸
int i; // ãªã³ã±ã¼ã¸ãªã
{
extern void f(); // å
é¨ãªã³ã±ã¼ã¸
extern int i; // å¤é¨ãªã³ã±ã¼ã¸
}
ãã®ä¾ã§ã¯ãååiã®ãªãã¸ã§ã¯ãã¯3ã¤åå¨ããããããããå
é¨ãªã³ã±ã¼ã¸ããªã³ã±ã¼ã¸ãªããå¤é¨ãªã³ã±ã¼ã¸ããã¤ãå¥ã®ãªãã¸ã§ã¯ããæã示ãã¦ããã
ããããããã¯ã¹ã³ã¼ãã®ååã¨ãåæ¹å®£è¨ãããåå空éã¹ã³ã¼ãã®ååã§ãååã«é©åããã¨ã³ãã£ãã£ãè¤æ°ãã£ãå ´åãã¨ã©ã¼ã¨ãªãããã®ãããªéè¤ããªãå ´åããããã¯ã¹ã³ã¼ãã®externæå®ããååã¯ãå¤é¨ãªã³ã±ã¼ã¸ãæã¤ã
ãããã¯ã¹ã³ã¼ãã§å®£è¨ãããååã§ãªã³ã±ã¼ã¸ãæã¤ãã®ãããã§ã«åæ¹å®£è¨ããã¦ããªãå ´åã¯ããããã¯ã¹ã³ã¼ããå
ãç´åã®åå空éã®ã¡ã³ãã¼ã¨ãªãããã ããåå空éã¹ã³ã¼ãã®ã¡ã³ãã¼ã®ååã¨ãã¦ç¾ãããã¨ã¯ãªãã
namespace ns
{
void f()
{
extern void h() ; // åå空énsã®ã¡ã³ãã¼ã¨ãªã
h() ; // OK
}
void g()
{
h() ; // ã¨ã©ã¼ãååhã¯å®£è¨ããã¦ããªã
}
void h() { } // ns::hã®å®£è¨ã¨å®ç¾©
}
// ããã¯ns::hã¨ã¯é¢ä¿ããªããå¥ã®ã¨ã³ãã£ãã£
void h() { }
ããã¾ã§ã®æ¡ä»¶ã«å½ã¦ã¯ã¾ããªãã£ãååã¯ããªã³ã±ã¼ã¸ãæããªããç¹ã«ããããã¯ã¹ã³ã¼ãã§å®£è¨ãããååã®ã»ã¨ãã©ã¯ããã§ã«ä¸ããæ¡ä»¶ã«ãã¦ã¯ã¾ããªãéãããªã³ã±ã¼ã¸ãæããªãã
åã®ãã¡ããªã³ã±ã¼ã¸ãæã¤ãã®ã¯ä»¥ä¸ã®éãã
-
ååãæã¤ã¯ã©ã¹åããããã¯enumåãtypedef宣è¨å
ã§å®ç¾©ãããç¡åã¯ã©ã¹åãç¡åenumåã ããtypedefåãæã¤ãã®ã§ããã®ååããªã³ã±ã¼ã¸ãæã¤ãã®
-
ãªã³ã±ã¼ã¸ãæã¤ã¯ã©ã¹ã®ä¸ã®ãç¡åã¯ã©ã¹ã¨ç¡åenumã®ã¡ã³ãã¼
-
ã¯ã©ã¹ãã³ãã¬ã¼ãã®ç¹æ®å
template < typename T >
void f() { }
void g()
{
f<int>() ;
}
ãã®ä¾ã§ã¯ãf<int>ã®ã¿ããªã³ã±ã¼ã¸ãæã¤ãf<short>ãf<double>ã®ãããªåã¯ãç¹æ®åããã¦ããªãã®ã§ããªã³ã±ã¼ã¸ãæããªã
-
åºæ¬å
-
ã¯ã©ã¹ã¨enum以å¤ã®è¤ååã§ããªã³ã±ã¼ã¸ãæã¤åãè¤åãã¦ãããã®ã
ãã¨ãã°ãint *ãint **ã¨è¨ã£ãåãªã³ã±ã¼ã¸ãæã¤
-
ãªã³ã±ã¼ã¸ããã¤åãCV修飾ãããå
ãªã³ã±ã¼ã¸ãæããªãåã¯ããªã³ã±ã¼ã¸ãæã¤é¢æ°ãã¯ã©ã¹ã§ä½¿ããã¨ã¯ã§ããªãããã ãã以ä¸ã®å ´åã¯ä½¿ããã¨ãã§ããã
-
ã¨ã³ãã£ãã£ãCè¨èªãªã³ã±ã¼ã¸ããã¤å ´å
-
ã¨ã³ãã£ãã£ãç¡ååå空éã§å®£è¨ããã¦ããå ´å
-
ã¨ã³ãã£ãã£ãODRã®æèã§ä½¿ããã¦ããªãå ´åããããã¯ãåã翻訳åä½ã§å®£è¨ããã¦ããå ´å
ç°ãªãã¹ã³ã¼ãã§å®£è¨ãããåä¸ã®äºã¤ã®ååã¯ã以ä¸ã®æ¡ä»¶ããã¹ã¦æºãããå ´åãåãå¤æ°ãé¢æ°ãåãenumããã³ãã¬ã¼ããåå空éãæã示ãã
-
ååã¯ä¸¡æ¹ã¨ããã¨ãã«å¤é¨ãªã³ã±ã¼ã¸ãæã¤ããã¨ãã«å
é¨ãªã³ã±ã¼ã¸ãæã¡ãåã翻訳åä½ã§å®£è¨ããã¦ããã
-
ååã¯ä¸¡æ¹ã¨ããåãåå空éã®ã¡ã³ãã¼ããæ´¾çã«ãããªãåãã¯ã©ã¹ã®ã¡ã³ãã¼ãæã示ãã¦ãã
-
ååã両æ¹ã¨ãé¢æ°ãæã示ãå ´åã¯ãé¢æ°ã®ä»®å¼æ°ã®åãªã¹ããåä¸ã§ãããã¨
-
ååã両æ¹ã¨ãé¢æ°ãã³ãã¬ã¼ããæã示ãå ´åã¯ãã·ã°ããã£ãåãã§ãããã¨
NOTE:ããããå
ã®Basic Conceptsã¯ãææ°ã®C++14ãã©ãããN3797ãåç
§ãã¦ãããããããå
ã¯C++11ã¨C++14ã®å·®ãæ¿ãããææ°ã®ãã©ãããåèãããã¨ã«ããã
ããã°ã©ã ä¸ã«ãããmainã¨ããååã®ã²ã¨ã¤ã®ã°ãã¼ãã«é¢æ°ãããããã°ã©ã ã¯éå§ãããfreestandingç°å¢ã§mainã®å®ç¾©ãå¿
è¦ã¨ãããã©ããã¯å®è£
ä¾åã§ããããã¹ãç°å¢ã¨éããfreestandingç°å¢ã§ã¯ãéå§ã¨çµäºãå®è£
ä¾åã¨ãªãã
mainé¢æ°ã¯ç¹å¥ãªæ±ããåãããC++ã®å®è£
ã¯ãmainãäºãå®ç¾©ãã¦ã¯ãªããªããmainé¢æ°ã¯ãªã¼ãã¼ãã¼ãã§ããªããæ»ãå¤ã®åã¯intã§ããããmainé¢æ°èªä½ã®åã¯å®è£
ä¾åã¨ãªãã
è¦æ ¼ã§ã¯ãC++ã®å®è£
ã¯ã以ä¸ã®äºã¤ã®å½¢ã®mainé¢æ°ãåãä»ããããã«è¦å®ããã¦ããã
-
é¢æ°ã§ãä»®å¼æ°ã()ã§ãintãè¿ããã®
int main() ;
auto main() -> int ;
-
é¢æ°ã§ãä»®å¼æ°ã( int, charã¸ã®ãã¤ã³ã¿ã¼ã¸ã®ãã¤ã³ã¿ã¼ )ã§ãintãè¿ããã®
int main( int, char ** ) ;
// ä»®å¼æ°ã«é
ååãæ¸ãã¨ããã¤ã³ã¿ã¼åã«ãªãã
int main( int, char *[] ) ;
2ã¤ç®ã®å½¢ã§ã¯ãæ
£ç¿çã«ãé¢æ°ã®1ã¤ç®ã®ä»®å¼æ°ã¯argcã¨å¼ã°ãã¦ãã¦ã2ã¤ç®ã®ä»®å¼æ°ã¯argvã¨å¼ã°ãã¦ãããargcã¯ããã°ã©ã ã®å®è¡ãããç°å¢ã§ãããã°ã©ã ã«æ¸¡ãããå¼æ°ã®æ°ã表ããargcãã¼ãã§ãªããã°ãå¼æ°ã¯argv[0]ãããargv[argc-1]ã¾ã§ãnullçµç«¯ããããã«ããã¤ãæååã®å
é æåã¸ã®ãã¤ã³ã¿ã¼ãæããargv[0]ã¯ãããã°ã©ã ãå®è¡ãããæã®ããã°ã©ã ã®ååãããããã¯""ã¨ãªããargcã®å¤ãè² æ°ã«ãªããã¨ã¯ãªããargv[argc]ã®å¤ã¯0ã¨ãªãã
#include <iostream>
int main( int argc, char ** argv )
{
std::cout << "Number of arguments: " << argc << std::endl ;
std::cout << "program name: " << argv[0] << std::endl ;
// æ®ãã®å¼æ°
for ( std::size_t i = 1 ; argv[i] != nullptr ; ++i )
{
std::cout << argv[i] << std::endl ;
}
}
mainé¢æ°ã¯ãããã°ã©ã ä¸ã§ä½¿ããã¦ã¯ãªããªããã使ããã¨ããã®ã¯ãå¼ã³åºããã¨ã¯ãã¡ãããã¢ãã¬ã¹ããªãã¡ã¬ã³ã¹ãåããã¨ãå«ã¾ããã
auto ptr = &main ; // ã¨ã©ã¼
mainã®ãªã³ã±ã¼ã¸ã¯å®è£
ä¾åã§ãããmainãdeleteå®ç¾©ããããinline, static, constexprãªã©ã¨å®£è¨ãããã¨ã¯ã¨ã©ã¼ã¨ãªãã
mainã¨ããååã¯ããã以å¤ã«ã¯äºç´ããã¦ããªããã¤ã¾ããã¯ã©ã¹åãenumåããã¯ã©ã¹ã®ã¡ã³ãã¼ãmainã¨åä»ãããã¨ã¯åé¡ãªãããã°ãã¼ãã«åå空é以å¤ã®åå空éã§mainã¨ããååã使ããã¨ãåé¡ã¯ãªãã
ä¾ãã°ã以ä¸ã®ã³ã¼ãã¯å®å
¨ã«åæ³ãªã³ã¼ãã§ããã
class main { } ;
namespace ns
{
int main() { return 0 ; }
}
int main( ) { }
3ã¤ã®mainã¨ããååã¯ãããããå¥ã®ã¨ã³ãã£ãã£ãæãã
std::exitãªã©ã®ãããªæ¹æ³ã使ãããããã¯ããæãåºããã«ããã°ã©ã ãçµäºãããå ´åãèªåã¹ãã¬ã¼ã¸ä¸ã®ãªãã¸ã§ã¯ãã¯ç ´æ£ãããªãããããstd::exitãstaticãã¹ã¬ããã¹ãã¬ã¼ã¸ä¸ã®ãªãã¸ã§ã¯ããç ´æ£ä¸ã«å¼ã°ãããªãã°ãããã°ã©ã ã®æåã¯æªå®ç¾©ã§ããã
mainé¢æ°ã®ä¸ã®returnæã¯ãããã°ã©ã ããã®é¢è±ã®å¹æããããèªåã¹ãã¬ã¼ã¸ä¸ã®ãªãã¸ã§ã¯ãã¯ç ´æ£ãããreturnæã®ãªãã©ã³ãã®å¤ããstd::exitã¸ã®å®å¼æ°ã¨ãã¦æ¸¡ãããããããmainé¢æ°ã®æå¾ã«å°éãã¦ããreturnæããªãå ´åã¯ã以ä¸ã®æãå®è¡ãããã®ã¨åçã®å¹æã«ãªãã
return 0 ;
ããã¯mainé¢æ°ã ãã®ç¹å¥ãªä»æ§ã§ããã
éãã¼ã«ã«å¤æ°ã«ã¯äºç¨®é¡ãããstaticã¹ãã¬ã¼ã¸ä¸ã®å¤æ°ã¨ãã¹ã¬ããã¹ãã¬ã¼ã¸ä¸ã®å¤æ°ã§ãããstaticã¹ãã¬ã¼ã¸ä¸ã®éãã¼ã«ã«é¢æ°ã¯ãããã°ã©ã ã®éå§ã«ã¨ããªã£ã¦åæåããããã¹ã¬ããã¹ãã¬ã¼ã¸ä¸ã®éãã¼ã«ã«é¢æ°ã¯ãã¹ã¬ããã®å®è¡ã«ã¨ããªã£ã¦åæåããããåæåã¯ä»¥ä¸ã®æé ã§è¡ãããã
staticã¹ãã¬ã¼ã¸ä¸ã¨ã¹ã¬ããã¹ãã¬ã¼ã¸ä¸ã®å¤æ°ã¯ãä»ã®åæåã«å
ããã¦ãå¿
ãã¼ãåæåãããã
å¤æ°ã«å®æ°åæåå(constant initializer)ãããå ´åãå®æ°åæå(constant initialization)ãè¡ããå ´åã¯ãè¡ããããå®æ°åæååã¨ã¯ãåæååãå®æ°å¼ã¨ãªãå¼ã®å ´åã§ããã
ã¼ãåæåã¨å®æ°åæåãã¾ã¨ãã¦ãéçåæå(static initialization)ã¨å¼ã¶ããã以å¤ã®åæåã¯ãã¹ã¦ãåçåæå(dynamic initialization)ã§ãããéçåæåã¯ãåçåæåã®åã«è¡ãããã
staticã¹ãã¬ã¼ã¸ä¸ã®éãã¼ã«ã«å¤æ°ã®åçåæåã®é åºããããã®ã¨ãé åºã®ãªããã®ãããã
æ示çã«ç¹æ®åãããã¯ã©ã¹ãã³ãã¬ã¼ãã®staticãã¼ã¿ã¡ã³ãã¼ã®åæåã¯ãé åºããããæé»ãæ示çã«å®ä½åãããç¹æ®åã®staticãã¼ã¿ã¡ã³ãã¼ã®åæåã¯ãé åºããªãã
template < typename T >
struct S
{
static int data ;
} ;
// å®è¡æé¢æ°
int init()
{
static int count = 0 ;
return count++ ;
}
// åçåæåããã
template < typename T >
int S<T>::data = init() ;
// æ示çå®ä½å
extern template struct S< int > ;
extern template struct S< short > ;
// æ示çç¹æ®å
template < >
int S<double>::data = init() ;
template < >
int S<float>::data = init() ;
int main( )
{
S<long> s1 ;
S<long long int> s2 ;
}
ã¯ã©ã¹ãã³ãã¬ã¼ãSã®short, int, long, long long intã«å¯¾ããç¹æ®åã¯ãæé»ãæ示çã«å®ä½åããã¦ããã®ã§ãstaticãã¼ã¿ã¡ã³ãã¼dataã®åæåã®é åºã¯ãªãããã®ãããå¤ãã©ããªããã¯ãè¦æ ¼ä¸å®ãããã¨ãã§ããªãã
ä¸æ¹ãfloatã¨doubleã«ã¤ãã¦ã®ç¹æ®åã¯ãæ示çã«ç¹æ®åããã¦ããã®ã§ãé åºããããdoubleã®ç¹æ®åãfloatã®ç¹æ®åããå
ããããã¨ãä¿è¨¼ããã¦ããã
ãã®ä»ã®staticã¹ãã¬ã¼ã¸ä¸ã®éãã¼ã«ã«å¤æ°ã¯é åºãããã
é åºãããå¤æ°ã¯ãã²ã¨ã¤ã®ç¿»è¨³åä½ã®ä¸ã§ã¯ãå®ç¾©ããã¦ããé çªéãã«åæåãããã
int init()
{
static int count = 0 ;
return count++ ;
}
int x = init() ; // 0
int y = init() ; // 1
int z = init() ; // 2
ãã®ä»ãè¦æ ¼ã§ã¯ãæåãå¤ãããªãå ´åãå®è£
ã¯åçåæåãéçåæåã«ãã¦ãããã§ããã¨ããmainé¢æ°ã«å¦çã移ã£ãæç¹ã§åæåãå®äºãã¦ããå¿
è¦ã¯ãªããªã©ã¨ãããã¨ãè¦å®ãã¦ãããããã¯å®è£
ã®é¸æãæé©åã許ãããã®ãã®ã§ãã³ã¼ãããè¦ããæåã¯å¤ãããªãã
mainé¢æ°ããreturnããããstd::exitãå¼ã³åºããå ´åãstaticã¹ãã¬ã¼ã¸ä¸ã®åæåããããªãã¸ã§ã¯ãã®ãã¹ãã©ã¯ã¿ã¼ãå¼ã³åºããããã¹ã¬ããã®åæé¢æ°ããreturnããããstd::exitãå¼ã³åºããå ´åãã¹ã¬ããã¹ãã¬ã¼ã¸ä¸ã®åæåããããªãã¸ã§ã¯ãã®ãã¹ãã©ã¯ã¿ã¼ãå¼ã³åºãããã
çµäºæã®ãªãã¸ã§ã¯ãã®ç ´æ£ä¸ã«ããã§ã«ç ´æ£ããããªãã¸ã§ã¯ããåç
§ããå ´åãæåã¯æªå®ç¾©ã§ããã
è¦æ ¼ä¸ãã¹ãã¬ã¼ã¸ã¨ããç¨èªã¯æ£ãããªããã¹ãã¬ã¼ã¸ã®æå¹æé(storage duration)ã¨ããç¨èªãæ£ããã®ã ããæ¬æ¸ã§ã¯å¤ãã®ç®æã§ãç°¡åã«ãããããåã«ã¹ãã¬ã¼ã¸ã¨ããè¨èã使ã£ã¦ããã
ã¹ãã¬ã¼ã¸ã®æå¹æéã«ã¯ãæ§ã
ãªãã®ãããããã®å
·ä½çãªå®è£
æ¹æ³ã¯è¦å®ããã¦ããªããè¦æ ¼ã¯C++ã®å®è£
ã®é¸æè¢ããªãã¹ãå¶éããªãããã«æ¸ããã¦ããã®ã§ãç´°é¨ã¯è¦å®ãã¦ããªãããã¨ãã°ãè¦æ ¼ã¯C++ã®ã¤ã³ã¿ã¼ããªã¿ã¼å®è£
ãç¦æ¢ãã¦ããªããããã§ã¯ãããããå¤å
¸çãªå®è£
ã®ä¸ä¾ããåã¹ãã¬ã¼ã¸ãã©ã®ããã«å®è£
ãã¦ãããããç°¡åã«è¨è¿°ããããè¦æ ¼ã®è¦å®ã§ã¯ãªããã¨ã«æ³¨æã
éçã¹ãã¬ã¼ã¸ã¨ãå¼ã°ããstaticã¹ãã¬ã¼ã¸ã®æå¹æé(static storage duration)ã¯ãstaticãã¼ã¯ã¼ããã¤ãã¦å®£è¨ãããã¼ã«ã«å¤æ°ããã¼ã¿ã¡ã³ãã¼ãthread_localãã¤ããã«å®£è¨ããåå空éã¹ã³ã¼ãã®å¤æ°ãªã©ã該å½ããã
æ¢åã®ããããC++ã®å®è£
ã§ã¯ãéçã¹ãã¬ã¼ã¸ã¯ãããã°ã©ã ã®ã³ã¼ããªã©ã¨ä¸ç·ã«ãã¤ããªä¸ã«é
ç½®ããããã®ã¾ã¾ã¡ã¢ãªä¸ã«èªã¿è¾¼ã¾ãã¦ããã
ã¹ã¬ããã¹ãã¬ã¼ã¸ã®æå¹æé(thread storage duration)ã¯ãthread_localãã¼ã¯ã¼ããã¤ãã¦å®£è¨ããå¤æ°ã該å½ããããã®å¤æ°ã¯ãã¹ã¬ãããã¨ã«ç°ãªããªãã¸ã§ã¯ããå²ãå½ã¦ããããã¹ã¬ããã®è§£èª¬ã¯æ¬æ¸ã®ç¯çã§ã¯ãªãã®ã§ã詳ããã¯èª¬æããªãã
æ¢åã®ããããC++ã®å®è£
ã§ã¯ãã¹ã¬ããã¹ãã¬ã¼ã¸ã¯ãTLSï¼Thread Local Storageï¼ãªã©ã¨å¼ã°ãããå®è£
ä¾åã®ã¹ã¬ãããã¨ã«å²ãå½ã¦ãããä½ããã®ã¹ãã¬ã¼ã¸ããããã¯ã¹ãã¬ã¼ã¸ãæã示ããã³ãã«ãªã©ãã確ä¿ãã¦ããã
èªåã¹ãã¬ã¼ã¸ã®æå¹æé(automatic storage duration)ã¯ããããã¯ã¹ã³ã¼ãã§æ示çã«registerã¤ãã§å®£è¨ãããå¤æ°ããããã¯ãstaticãexternã¤ãã§å®£è¨ããã¦ããªãå¤æ°ã該å½ãããthread_localã¤ãã®å¤æ°å®£è¨ã¯æé»çã«staticã§ãããã®ã§ã該å½ããªãã
æ¢åã®ããããC++ã®å®è£
ã§ã¯ãèªåã¹ãã¬ã¼ã¸ã®æå¹æéã¯ãã¹ã¿ãã¯ã¨å¼ã°ããç¹å¥ãªã¡ã¢ãªããå²ãå½ã¦ãããã
åçã¹ãã¬ã¼ã¸ã®æå¹æé(dynamic storage duration)ãæã¤ã¹ãã¬ã¼ã¸ä¸ã®ãªãã¸ã§ã¯ãã¯ãnewå¼ã«ãã£ã¦åçã«ä½æãããdeleteå¼ã«ãã£ã¦ç ´æ£ãããã
C++å®è£
ã¯ããªãã¸ã§ã¯ããæ§ç¯ããåçã¹ãã¬ã¼ã¸ã確ä¿ããããã®ã°ãã¼ãã«ãªç¢ºä¿é¢æ°(allocation function)ã¨ãåçã¹ãã¬ã¼ã¸ã解æ¾ããããã®è§£æ¾é¢æ°(deallocation function)ãæä¾ãã¦ããã
確ä¿é¢æ°ã¯ãoperator newã¨operator new[]ã§ã解æ¾é¢æ°ã¯operator deleteã¨operator delete[]ã¨ãªãã
C++ã®æ¨æºã©ã¤ãã©ãªã¯ãããã©ã«ãã®ç¢ºä¿é¢æ°ã¨è§£æ¾é¢æ°ã®å®ç¾©ãæä¾ãã¦ãããããã¯ãªã¼ãã¼ãã¼ããã¦ãç¬èªã®å®ç¾©ãä¸ãããã¨ãã§ããã
確ä¿é¢æ°ã解æ¾é¢æ°ã®ã·ã°ããã£ã¯ã以ä¸ã®éãã
void* operator new(std::size_t);
void* operator new[](std::size_t);
void operator delete(void*);
void operator delete[](void*);
void operator delete(void*, std::size_t) noexcept;
void operator delete[](void*, std::size_t) noexcept;
æå¾ã®äºã¤ã®è§£æ¾é¢æ°ã¯ãäºçªç®ã®ä»®å¼æ°ã«ã確ä¿ããã¹ãã¬ã¼ã¸ã®ãµã¤ãºã渡ãããã
確ä¿é¢æ°ã¯ãã¯ã©ã¹ã®ã¡ã³ãã¼é¢æ°ããã°ãã¼ãã«é¢æ°ã§ãªããã°ãªããªããã°ãã¼ãã«åå空é以å¤ã®åå空éã§ç¢ºä¿é¢æ°ã宣è¨ããããã°ãã¼ãã«åå空éã§staticã¨ãã¦ç¢ºä¿é¢æ°ã宣è¨ããã¨ãããã°ã©ã ã¯ã¨ã©ã¼ã¨ãªãã
確ä¿é¢æ°ã®æ»ãå¤ã®åã¯void *ã§ãªããã°ãªããªããæåã®ä»®å¼æ°ã¯ãstd::size_tåã§ãããã©ã«ãå®å¼æ°ããã£ã¦ã¯ãªããªããæåã®å¼æ°ã«ã¯ã確ä¿é¢æ°ã確ä¿ãã¹ãã¹ãã¬ã¼ã¸ã®ãµã¤ãºã渡ãããã
確ä¿é¢æ°ã¯ãã³ãã¬ã¼ã宣è¨ã§ããããæ»ãå¤ã®åã¨æåã®ä»®å¼æ°ã¯ãåè¿°éãã§ãªããã°ãªããªãã確ä¿é¢æ°ã®ãã³ãã¬ã¼ãã¯ãäºã¤ä»¥ä¸ã®ä»®å¼æ°ãæããã°ãªããªãã
確ä¿é¢æ°ã¯ãè¦æ±ããããµã¤ãºä»¥ä¸ã®ã¹ãã¬ã¼ã¸ã確ä¿ã§ãããªãã°ããã®ã¹ãã¬ã¼ã¸ã®å
é ã¢ãã¬ã¹ãè¿ããã¹ãã¬ã¼ã¸ã®ä¸èº«ã®å¤ã«ã¤ãã¦ã¯ãæªè¦å®ã§ããã
確ä¿é¢æ°ã®è¿ããã¤ã³ã¿ã¼ã¯ãã©ã®åºæ¬ã¢ã©ã¤ã¡ã³ãè¦æ±ãæºããã¢ãã¬ã¹ã§ãªããã°ãªããªãã
確ä¿é¢æ°ãã¹ãã¬ã¼ã¸ã®ç¢ºä¿ã«å¤±æããå ´åãç»é²ããã¦ããnewãã³ãã©ã¼ãããã°å¼ã³åºãã確ä¿é¢æ°ãç¡ä¾å¤æå®ããã¦ããå ´åã¯ãnullãã¤ã³ã¿ã¼ãè¿ããããã§ãªããã°std::bad_allocåã®ä¾å¤ãthrowãããã
解æ¾é¢æ°ã¯ã¯ã©ã¹ã®ã¡ã³ãã¼é¢æ°ããã°ãã¼ãã«é¢æ°ã§ãªããã°ãªããªããã°ãã¼ãã«åå空é以å¤ã®åå空éã§è§£æ¾é¢æ°ã宣è¨ããããã°ãã¼ãã«åå空éã§staticã¨ãã¦è§£æ¾é¢æ°ã宣è¨ããã¨ãããã°ã©ã ã¯ã¨ã©ã¼ã¨ãªãã
解æ¾é¢æ°ã®æ»ãå¤ã®åã¯voidãæåã®ä»®å¼æ°ã¯ãvoid *ã§ãªããã°ãªããªãã
C++14ã§ã¯ã解æ¾é¢æ°ã2åã®ä»®å¼æ°ãæã¡ã第äºå¼æ°ãstd::size_tåã§ããå ´åã2ã¤ç®ã®ä»®å¼æ°ã«ã¯ã確ä¿ããã¹ãã¬ã¼ã¸ã®ãµã¤ãºã渡ãããã
解æ¾é¢æ°ããä¾å¤ãæãã¦æãã ããå ´åãæåã¯æªå®ç¾©ã§ããã
解æ¾é¢æ°ã®1ã¤ç®ã®å®å¼æ°ãnullãã¤ã³ã¿ã¼ã§ãªããã°ã解æ¾é¢æ°ã¯ãã¤ã³ã¿ã¼ã®æã示ãã¹ãã¬ã¼ã¸ã®è§£æ¾ãè¡ãã
C++11ã«ã¯ã¬ãã¼ã¸ã³ã¬ã¯ã·ã§ã³ã¯ãªãããå°æ¥ã¬ãã¼ã¸ã³ã¬ã¯ã·ã§ã³ã追å ãããã¨ãè¦è¶ãã¦ãå®å
¨ãªãã¤ã³ã¿ã¼(safely-derived pointer)ã¨ãããã®ãå®ç¾©ãã¦ããã
ã¬ãã¼ã¸ã³ã¬ã¯ã·ã§ã³ã¨ã¯ãåçã¹ãã¬ã¼ã¸ã®æ示çãªè§£æ¾ãããªãã¦ãè¯ããªãè¨èªæ©è½ã§ããã
ã¬ãã¼ã¸ã³ã¬ã¯ã·ã§ã³ã®å®è£
æ¹æ³ã¨ãã¦ã¯ãããã°ã©ã ä¸ã®ãã¤ã³ã¿ã¼ã®å¤ãæ¤è¨¼ããã©ããããåç
§ããã¦ããªãåçã¹ãã¬ã¼ã¸ãæ¢ãã ãæ¹æ³ãããããããããã¹ãã¬ã¼ã¸ãåç
§ããæ¹æ³ããªããã°ããã®ã¹ãã¬ã¼ã¸ã¯ãã¯ã使ããã¦ããªãã®ã ããã解æ¾ãã¦ãåé¡ããªãã¨ãããã¨ã«ãªãã
ããããC++ã¯ããã¤ã³ã¿ã¼ã«å¯¾ããä½ç´ãªæä½ãæä¾ãã¦ãããå³å¯ã«ã¯æªå®ç¾©ã®æåã«ãªããããã¤ã³ã¿ã¼ã®å¤ãreinterpret_castã§ãã®ã¾ã¾æ´æ°åã«åå¤æãã¦ãæ´æ°åã¨ãã¦æ¼ç®ãããã§ããããã®ãããªããã¤ã³ã¿ã¼ã®å
é¨è¡¨ç¾ãå¤æ´ãã¦ãå¾ããå
ã®å
é¨è¡¨ç¾ã«æ»ããããªå¦çã¨ãããã°ã©ã ä¸ã®å
¨ãã¤ã³ã¿ã¼ã®å¤ãæ¤è¨¼ãã¦ãã©ããããåç
§ããã¦ããªãã¹ãã¬ã¼ã¸ãæ¢ãã ãã¨ããã¬ãã¼ã¸ã³ã¬ã¯ã·ã§ã³ã®æ©è½ã¯ãç¸æ§ãæªãã
ãã®ãããC++11ã§ã¯ãã©ããããã¤ã³ã¿ã¼ã®æä½ã¯å®å
¨ãªã®ãã¨ãããã¨ã«ã¤ãã¦ãè²ã
ã¨å®ç¾©ãã¦ããããã®è©³ç´°ã¯ãæ¬æ¸ã§ã¯è§£èª¬ããªãã
ãµããªãã¸ã§ã¯ãã®ã¹ãã¬ã¼ã¸ã®æå¹æéã¯ããã®å®å
¨ãªãªãã¸ã§ã¯ãã®æå¹æéã«åãã
ãªãã¸ã§ã¯ãã®å¯¿å½(lifetime)ã®å§ã¾ãã¯ããªãã¸ã§ã¯ãã®åã®ãµã¤ãºã¨ã¢ã©ã¤ã¡ã³ãã«é©åã«å¯¾å¿ããã¹ãã¬ã¼ã¸ã確ä¿ãããå¾ããããªãã¸ã§ã¯ããéããªãã¢ã«åæåãæã¤ãªãã°ããã®åæåãçµãã£ãæç¹ã§ããã
éããªãã¢ã«åæå(non-trivial initialization)ã¨ã¯ããªãã¸ã§ã¯ãã®åãã¯ã©ã¹ãã¢ã°ãªã²ã¼ãã§ããã®ã¡ã³ãã¼ãã²ã¨ã¤ã§ãããªãã¢ã«ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ä»¥å¤ã§åæåããããã®ãããã
ãªãã¸ã§ã¯ãã®å¯¿å½ã®çµããã¯ããªãã¸ã§ã¯ããéããªãã¢ã«ãã¹ãã©ã¯ã¿ã¼ãæã¤ã®ãªãã°ããã¹ãã©ã¯ã¿ã¼å¼ã³åºããéå§ããæç¹ãããã§ãªããã°ããªãã¸ã§ã¯ãã®å ããã¹ãã¬ã¼ã¸ã解æ¾ããããåå©ç¨ãããæç¹ã§ããã
ããªãã¢ã«ã«ã³ãã¼å¯è½ãªåã®ãªãã¸ã§ã¯ãã¯ããã®å
é¨è¡¨ç¾ã®ãã¤ãåããcharãunsigned charã®é
åã«ã³ãã¼ã§ãããã³ãã¼ãããcharãunsigned charã®é
åããåã³ãªãã¸ã§ã¯ãã«ã³ãã¼ããªãããå ´åããªãã¸ã§ã¯ãã¯å
ã®å¤ãä¿æããã
// ããªãã¢ã«ã«ã³ãã¼å¯è½ãªåTã®ãªãã¸ã§ã¯ã
T object ;
// Tã表ç¾ãããã¤ãåã®ãµã¤ãº
constexpr std::size_t size = sizeof(T) ;
// Tåã¨åããµã¤ãºã®é
å
unsigned char buffer[size] ;
// é
åã«ã³ãã¼
std::memcpy( buffer, &object, size ) ;
// å
ã®ãªãã¸ã§ã¯ãã«ã³ãã¼ããªãã
std::memcpy( &object, buffer, size ) ;
// objectã®å¤ã¯å
ã®ã¾ã¾
ããªãã¢ã«ã«ã³ãã¼å¯è½ãªåTã®ãªãã¸ã§ã¯ããæã示ããã¤ã³ã¿ã¼ãäºã¤ããã¨ãã¦ããªãã¸ã§ã¯ãã¯åºæ¬ã¯ã©ã¹ã¨ãã¦ã®ãµããªãã¸ã§ã¯ãã§ã¯ãªãå ´åãå
é¨è¡¨ç¾ã®ãã¤ãåããã¤ã³ã¿ã¼ãçµç±ãã¦ã³ãã¼ããã¨ãã³ãã¼ãããæ¹ã¯ã³ãã¼ããæ¹ã®å¤ã«ãªãã
// Tã¯ããªãã¢ã«ã«ã³ãã¼å¯è½ãªå
// ãã¤ã³ã¿ã¼ã¯ãªãã¸ã§ã¯ããæã示ãã¦ããã¨ãã
T * ptr1 ;
T * ptr2 ;
std::memcpy( ptr1, ptr2, sizeof(T) ) ;
// ptr1ã®æã示ããªãã¸ã§ã¯ãã¯ãptr2ã®æã示ããªãã¸ã§ã¯ãã¨åãå¤ã«ãªã
ããåTã®ãªãã¸ã§ã¯ãã®ãªãã¸ã§ã¯ã表ç¾(object representation)ã¯ãNãsizeof(T)ã¨ããã¨ãNåã®unsigned charåã®ãªãã¸ã§ã¯ãã«ãªãããªãã¸ã§ã¯ãã®å¤è¡¨ç¾(value representation)ã¯ãTåã®å¤ãä¿æããããã®ãããåã§ãããããªãã¢ã«ã«ã³ãã¼å¯è½ãªåã®å ´åãå¤è¡¨ç¾ã¯ããªãã¸ã§ã¯ã表ç¾ã®ãããåã®å¤ã¨ãããã¨ãã§ããããã®å¤ã¯å®è£
ä¾åã®ãããåã®å¤ã§ããã
宣è¨ããã¦ãããå®ç¾©ããã¦ããªãã¯ã©ã¹ãä¸é¨ã®enumã大ããã®åãããªãé
åãä¸å®å
¨ãªè¦ç´ åã®é
åã¯ãä¸å®å
¨ã«å®ç¾©ããããªãã¸ã§ã¯ãåã§ããããã®ãããªä¸å®å
¨ã«å®ç¾©ããããªãã¸ã§ã¯ãåã¯ããã®ãµã¤ãºãã¹ãã¬ã¼ã¸ä¸ã®ã¬ã¤ã¢ã¦ãããã¾ã å®ã¾ã£ã¦ããªãããªãã¸ã§ã¯ãã¯ãä¸å®å
¨ãªåãæã£ãã¾ã¾å®ç¾©ããã¦ã¯ãªããªãã
struct incomplete ; // ä¸å®å
¨å
struct error
{
incomplete i ; // ã¨ã©ã¼ãä¸å®å
¨ãªåããã£ãã¾ã¾å®ç¾©
} ;
ã¯ã©ã¹åã¯ã翻訳åä½ã®ããç®æã§ã¯ä¸å®å
¨ã§ãå¾ã«å®å
¨ã«ãªããã¨ãã§ããããã®å ´åã§ããã¯ã©ã¹ã®åã¯å¤ãããªãã
é
åã®åã¯ãè¦ç´ ã¨ãã¦ä¸å®å
¨ãªã¯ã©ã¹åãå«ã¿ãä¸å®å
¨ã¨ãªããã¨ãããããããã¯ã©ã¹ãå¾ã«å®å
¨ã«ãªã£ããªãã°ããã®ãããªé
ååãããã®æç¹ã§å®å
¨ã«ãªãã
class X ; // ä¸å®å
¨å
using type = X [10] ; // OKãä¸å®å
¨å
type a ; // ã¨ã©ã¼ãé
åã®è¦ç´ åãä¸å®å
¨
// ã¯ã©ã¹Xãå®å
¨ã«ãã
class X { } ;
type b ; // OKãé
åã®è¦ç´ åã¯å®å
¨
宣è¨ãããé
åã¯è¦ç´ æ°ãä¸å®ã¨ãããã¨ãã§ãããã®æç¹ã§ã¯ä¸å®å
¨ãªåã¨ãªãããã®ãããªé
åã¯ãå¾ã«å®å
¨ã«å®ç¾©ãããã¨ãã§ãããé
åã®åã¯ãè¦ç´ æ°ãæå®ãããåã¨å¾ã¨ã§ç°ãªããè¦ç´ ã®åãTã¨ããã¨ãè¦ç´ æ°ãæå®ãããåã®åã¯ããTåã®è¦ç´ æ°ä¸å®ã®é
ååãã§ãããè¦ç´ æ°ãNã«å®ã¾ã£ãå¾ã¯ããTåã®Nè¦ç´ æ°ã®é
åãã¨ãªãã
extern int a[] ; // intåã®è¦ç´ æ°ä¸å®ã®é
åå
int a[10] ; // intåã®è¦ç´ æ°10ã®é
åå
ãªãã¸ã§ã¯ãå(object type)ã¨ããç¨èªã¯ãCV修飾ããã¦ãããããããªãåã§ãé¢æ°åããªãã¡ã¬ã³ã¹åãvoidå以å¤ã®åã®ãã¨ã§ããã
æ¼ç®å(Arithmetic type)ãenumåããã¤ã³ã¿ã¼åãã¡ã³ãã¼ã¸ã®ãã¤ã³ã¿ã¼åãstd::nullptr_tåãããã¦ãããã®åã®CV修飾ãããåãã²ã£ãããã¦ãã¹ã«ã©ã¼å(scalar type)ã¨å¼ã¶ãã¹ã«ã©ã¼åã¨PODã¯ã©ã¹ãã¾ããã®ãããªåã®é
åã¨ããã®ãããªåãCV修飾ãããåãã²ã£ãããã¦ãPODåã¨å¼ã¶ãã¹ã«ã©ã¼åã¨ããªãã¢ã«ã«ã³ãã¼å¯è½ãªã¯ã©ã¹åããã®ãããªåã®é
åãévolatileã§const修飾ããããããã®åãã²ã£ãããã¦ãããªãã¢ã«ã«ã³ãã¼å¯è½ãªå(trivially copyable type)ã¨å¼ã¶ãã¹ã«ã©ã¼åãããªãã¢ã«ã¯ã©ã¹åããã®ãããªåã®é
åããã®ãããªåã®CV修飾ãããåãã²ã£ãããã¦ãããªãã¢ã«å(trivial type)ã¨å¼ã¶ãã¹ã«ã©ã¼åãæ¨æºã¬ã¤ã¢ã¦ãã¯ã©ã¹åããã®ãããªåã®é
åããã®ãããªåã®CV修飾ãããåãã²ã£ãããã¦ãæ¨æºã¬ã¤ã¢ã¦ãå(standard layout type)ã¨å¼ã¶ã
ãªãã©ã«å(literal type)ã¨ã¯ã以ä¸ã®æ¡ä»¶ã®ããããã²ã¨ã¤ãæºããåã®ãã¨ã§ããã
T1åã¨T2åãåãã§ãããªãã°ãT1ã¨T2ã¯ãã¬ã¤ã¢ã¦ãäºæå(layout-compatible type)ã§ããã
æå(char)ã®ãªãã¸ã§ã¯ãã¯ãåºæ¬æåã»ããããã¹ã¦è¡¨ç¾ã§ãã大ãããæã¤ãåºæ¬æåã»ããã®æåãæåãªãã¸ã§ã¯ãã«æ ¼ç´ããã¦ããå ´åãæåãªãã¸ã§ã¯ãã®æ´æ°ã®å¤ã¨ããã®æåã®æåãªãã©ã«ã®å¤ã¯ãçãããªãã
char c = 'A' ;
c == 'A' ; // true
charåãè² æ°ã表ç¾ã§ãããã©ããã¯ãå®è£
ä¾åã§ããã
char c = static_cast<char>(-1) ; // å®è£
ä¾å
æååã¯ãæ示çã«unsignedãsignedã§å®£è¨ã§ãããchar, signed char, unsigned charã¯ãããããå¥ã®åã¨ãã¦åºå¥ãããããã®3ã¤ã®åããããã¼æåå(çãæååãnarrow character type)ã¨å¼ã¶ã
ã²ã¨ã¤ã®char, signed char, unsigned charåã®ãªãã¸ã§ã¯ãã¯åã大ããã®ã¹ãã¬ã¼ã¸ãå ããã¢ã©ã¤ã¡ã³ãè¦æ±ãåãã§ãããã¤ã¾ãã3ã¤ã®åãåããªãã¸ã§ã¯ã表ç¾ãæã¤ã
ããã¼æååã§ã¯ããªãã¸ã§ã¯ã表ç¾ãæ§æãããã¹ã¦ã®ãããåããå¤è¡¨ç¾ã¨ãã¦ä½¿ãããã符å·ãªããªããã¼æååã§ã¯ããªãã¸ã§ã¯ã表ç¾ã®ãã¹ã¦ã®ãããåããå¤è¡¨ç¾ã®æ°å¤ã表ç¾ããã®ã«ä½¿ãããããã®ç¹ã§ãããã¼æååã¯ãä»ã®åã«ã¯ãªãç¬èªã®ç¹å¾´ãæã¤ãæ
£ç¿çã«ããã¼æååã¯ä»»æã®ãã¤ãåã表ç¾ããã®ã«ä½¿ããã¦ããã
charåã®ãªãã¸ã§ã¯ãã®å¤ã¯ãsigned charãunsigned charã®ã©ã¡ããã®å¤ã¨çãããã©ã¡ãã¨çãããªãã®ãã¯ãå®è£
ã«å§ãããã¦ããã
char c = 'A' ;
signed char sc = 'A' ;
unsigned char uc = 'A' ;
ãã®ä¾ã§ã¯ãè¦æ ¼æºæ ã®å®è£
ã§ã¯ãcã®å¤ã¯ãscãucã®ã©ã¡ããã¨å¿
ãçãããªããã©ã¡ãã¨çããã®ãã¯è¦å®ããã¦ããªãã
æ¨æºç¬¦å·ã¤ãæ´æ°å(standard signed integer type)ã«ã¯ã5種é¡ããã
signed char
short int
int
long int
long long int
ãã®ä¸¦ã³é ã¯ãå°ããé ã§ãããæ¨æºç¬¦å·ã¤ãæ´æ°åã¯ãå°ãªãã¨ããã®é åºã«ããããåã®åã®å¤ã¨åãããã以ä¸ã®å¤§ããã®ã¹ãã¬ã¼ã¸ãå ããã
åºæ¬å(Fundamental types)
ãã®ä»ã«ãå®è£
ä¾åã®æ¡å¼µç¬¦å·ã¤ãæ´æ°å(extended signed integer type)ããããããã¯ãå
·ä½çã«ã¯è¦æ ¼ã§å®ç¾©ãããªãããå®è£
ãç¬èªã«æä¾ãã符å·ä»ãã®æ´æ°åãæããæ¨æºç¬¦å·ã¤ãæ´æ°åã¨ãæ¡å¼µç¬¦å·ã¤ãæ´æ°åãã²ã£ãããã¦ã符å·ã¤ãæ´æ°å(signed integer type)ã¨å¼ã¶ã
ç´ ã®intã¯ãå®è¡ç°å¢ã®ã¢ã¼ããã¯ãã£ã«ã¨ã£ã¦èªç¶ãªãµã¤ãºã¨ãªãã
ããããã®æ¨æºç¬¦å·ã¤ãæ´æ°åã«å¯¾å¿ãããæ¨æºç¬¦å·ãªãæ´æ°å(standard unsigned integer type)ãåå¨ããã
unsigned char
unsigned short int
unsigned int
unsigned long int
unsigned long long int
ããããã対å¿ããæ¨æºç¬¦å·ã¤ãæ´æ°åã¨ãåã大ããã®ã¹ãã¬ã¼ã¸ãåãã¢ã©ã¤ã¡ã³ãè¦æ±ãæã¤ãã¤ã¾ãã符å·ã¤ãã®æ´æ°åã¨å¯¾å¿ãã符å·ãªãã®æ´æ°åã¯ãããããããªããªãã¸ã§ã¯ã表ç¾ãæã¤ã
sizeof( int ) == sizeof( unsigned int ) ; // true
alignof( int ) == alignof( unsigned int ) ; // true
æ¨æºç¬¦å·ã¤ãæ´æ°åã¨åãããã«ãæ¨æºç¬¦å·ãªãæ´æ°åã«ããå®è£
ä¾åã®æ¡å¼µç¬¦å·ãªãæ´æ°å(extended unsigned integer type)ãåå¨ããããããããããã対å¿ããæ¡å¼µç¬¦å·ã¤ãæ´æ°åã¨ããªã大ããã®ã¹ãã¬ã¼ã¸ã¨ã¢ã©ã¤ã¡ã³ãè¦æ±ãæã¤ã
æ¨æºç¬¦å·ãªãæ´æ°åã¨æ¡å¼µç¬¦å·ãªãæ´æ°åãã²ã£ãããã¦ã符å·ãªãæ´æ°å(unsigned integer type)ã¨å¼ã¶ã
符å·ã¤ãæ´æ°åã¨å¯¾å¿ãã符å·ãªãæ´æ°ã®åã®ãå¤è¡¨ç¾ã¯åãã§ããã
æ¨æºç¬¦å·ã¤ãæ´æ°åã¨æ¨æºç¬¦å·ãªãæ´æ°åãã²ã£ãããã¦ãæ¨æºæ´æ°å(standard integer type)ã¨å¼ã¶ãæ¡å¼µç¬¦å·ã¤ãæ´æ°åã¨æ¡å¼µç¬¦å·ãªãæ´æ°åãã²ã£ãããã¦ãæ¡å¼µæ´æ°å(extended integer type)ã¨å¼ã¶ã
C++ã®æ´æ°åã¯ãCè¨èªã®æ¨æºè¦æ ¼ã§å®ç¾©ããã¦ããè¦ä»¶ã¨åãè¦ä»¶ãæºãããã¤ã¾ããCã¨C++ã¯ãã®ç¹ã«ããã¦äºææ§ãããã
符å·ãªãæ´æ°ã¯ãã¢ã¸ã¥ãã®2nã®æ³(laws of arithmetic modulo 2n)ã«å¾ããnã¯æ´æ°åã®å¤è¡¨ç¾ã®ãããæ°ã§ãããããã¯ã符å·ãªãæ´æ°åã¯ã絶対ã«ãªã¼ãã¼ããã¼ããªããã¨ãè¦æ ¼ä¸ä¿è¨¼ããã¦ãããã¨ãæå³ãããä½æ
ãªãã°ããããã符å·ãªãæ´æ°åã§è¡¨ç¾ã§ããå¤ãè¶
ããã¨ãããªãã°ããã®çµæã¯ã表ç¾ã§ããæ大å¤ã§ã®å°ä½ã«ãªãããã ã
ä¾ãã°ãè¦æ ¼æºæ ã®C++å®è£
ã§ã¯ã以ä¸ã®ã³ã¼ãã®nã¨mã®å¤ã¯ãä¿è¨¼ããã¦ããã
int main()
{
// nã®å¤ã¯ãunsigned intã§è¡¨ç¾ã§ããæ大å¤
unsigned int max = std::numeric_limits<unsigned int>::max() ;
unsigned int n = max + 1 ; // nã®å¤ã¯0
unsigned int m = max + 2 ; // mã®å¤ã¯1
}
wchar_tã¯ãå
é¨å(underlying type)ã¨å¼ã°ãããä½ããã®æ´æ°åã¨åããµã¤ãºã符å·ãã¢ã©ã¤ã¡ã³ãè¦æ±ãæã¤ããã®å
é¨åã¯ãå®è£
ã«å§ãããã¦ããã
wchar_tåã®ã²ã¨ã¤ã®ãªãã¸ã§ã¯ãã¯ãå®è£
ããµãã¼ããããã±ã¼ã«ã®æåã»ããã®ä»»æã®ä¸æåã表ç¾ã§ããã
wchar_tã¯ãå°ãªãã¨ããè¦æ ¼ä¸ã¯ãããªã£ã¦ãããããããç¾å®çã«ã¯ããã®ãããªåºå®é·ã®æåã³ã¼ãã¯ããµãã¼ããããã±ã¼ã«ã¨æåã»ããã大å¹
ã«éå®ããªããã°ãåå¨ããªãããã¨ãã°ãããå®è£
ã§ã¯ãwchar_tã¯16bitã®UTF-16ã®1åä½ã表ç¾ããããã«ãªã£ã¦ãããããããUTF-16ã®1åä½ã¯ãUnicodeã®æåã»ããã®ä»»æã®ä¸æåã表ç¾ã§ããªããããå®è£
ã§ã¯32bitã®UTF-32ã®1åä½ã表ç¾ããããã«ãªã£ã¦ããããUTF-32ãã1åä½ã§ä»»æã®1æåã表ããæåã®ã¨ã³ã³ã¼ãæ¹å¼ã§ã¯ãªããwchar_tã®å
é¨åãè¦æ ¼ã§è¦å®ããã¦ããªããã¨ã«ãããwchar_tã®ä»æ§ã¯ã移æ¤æ§ã®åé¡ãå¼ãèµ·ããã
char16_tåã¯å
é¨åuint_least16_tåã¨ãchar32_tåã¯å
é¨åuint_least32_tåã¨ãããããçãã大ããã符å·ãã¢ã©ã¤ã¡ã³ãè¦æ±ãæã¤ã
boolåã®åãå¾ãå¤ã¯ãtrueãfalseã§ãããboolåã«ã¯ãsigned, unsigned short, longã¨ãã£ãå¤ç¨®ã¯åå¨ããªãã
bool, char, char16_t, char32_t, wchar_tã符å·ä»ãæ´æ°åã¨ç¬¦å·ãªãæ´æ°åãã²ã£ãããã¦ãæ´æ°å(integral typeãããã¯integer type)ã¨å¼ã¶ã
æ´æ°åã®å
é¨è¡¨ç¾ã¯ãä½ããã®ç´ç²ãªäºé²æ°ã§ããã¨è¦å®ããã¦ãããè¦æ ¼ã¯ãæ´æ°åã®å
é¨è¡¨ç¾ã«ã¤ãã¦å®è£
ä¾åãèªãã¦ãããä¾ãã°ãç¾å®ã®ä¾ãã ãã¨ã2ã®è£æ°ã ã¨ã1ã®è£æ°ã ã¨ãã符å·ã®è¡¨ç¾æ¹æ³ã ã¨ããã¨ã³ãã£ã¢ã³ãªã©ãæ´æ°ããããåã§è¡¨ç¾ããã«ã¯ãæ§ã
ãªå®è£
æ¹æ³ãèãããããC++ã®è¦æ ¼ã¯ããã®è©³ç´°ãè¦å®ããªãã
æµ®åå°æ°ç¹æ°å(floating point type)ã«ã¯ãfloat, double, long doubleããããdoubleã¯å°ãªãã¨ãfloatã¨åç以ä¸ã®ç²¾åº¦ããããlong doubleã¯doubleã¨åç以ä¸ã®ç²¾åº¦ãããã
æµ®åå°æ°ç¹æ°åãå¤ã表ç¾ããæ¹æ³ã¯ãå®è£
ä¾åã§ãããæ´æ°åã¨æµ®åå°æ°ç¹æ°åãã²ã£ãããã¦ãæ¼ç®å(arithmetic type)ã¨å¼ã¶ã
voidåã¯ã空ã®å¤ãæã¤ãå¤ã表ç¾ããªãåã®ãããªãã®ã ãvoidåã¯å¸¸ã«ä¸å®å
¨ãªåã§ãããå®å
¨ã«ããæ¹æ³ã¯ãªãã
voidåã¯ãé¢æ°ãæ»ãå¤ãè¿ããªãå ´åã«ãæ»ãå¤ã®åã¨ãã¦ä½¿ãããã
// æ»ãå¤ãè¿ããªãé¢æ°
void f() { }
ããããå¼ã¯ãæ示çã«voidåããCV修飾åã¤ãã®voidåã«åå¤æã§ããã
// intåã®å¤0ãvoidåã®ç©ºã®å¤ã«å¤æ
static_cast<void>(0) ;
voidåã®å¼ã使ããå ´æã¯ã以ä¸ã®éãã
-
å¼æ
-
ã³ã³ãå¼ã®ãªãã©ã³ã
-
æ¡ä»¶æ¼ç®åã®2ã¤ç®ã¨3ã¤ç®ã®ãªãã©ã³ã
-
typeidã®ãªãã©ã³ã
-
noexcept
-
decltype
-
æ»ãå¤ã®åãvoidã®é¢æ°ã®æ¬ä½ã®returnæã®ä¸ã®å¼
-
voidåãCV修飾åã¤ãã®voidåã¸ã®åå¤æã®ãªãã©ã³ã
#include <typeinfo>
// å¼ã³åºãã¨voidåã®å¼ã«ãªãé¢æ°
void f() { }
void g()
{
f() ; // å¼æ
f() , f() ; // ã³ã³ãå¼ã®ãªãã©ã³ã
true ? f() : f() ; // æ¡ä»¶æ¼ç®å
typeid( f() ) ; // typeid
noexcept( f() ) ; // noexceptæ¼ç®å
using type = decltype( f() ) ; // decltype
return f() ; // returnæ
static_cast<void>( f() ) ; // voidåã¸ã®åå¤æ
}
std::nullptr_tåã®å¤ã¯ãnullãã¤ã³ã¿ã¼å®æ°ã§ãããnullãã¤ã³ã¿ã¼å®æ°ã«ã¯ãnullptrã¨ããç¹å¥ãªãã¼ã¯ã¼ãã®ãªãã©ã«ããããsizeof(std::nullptr_t)ã¯sizeof(void*)ã¨çãããªãã
ãã¨ããããC++ã®å®è£
ã§ããããã®ç°ãªãåã¨ãã¦èªèãããåºæ¬åã®å
é¨è¡¨ç¾ãåãã ã£ãã¨ãã¦ããåã¯ç°ãªããã®ã¨èªèãããã
è¤ååã¨ã¯ããã¤ã³ã¿ã¼ãé
åããã¤ã³ã¿ã¼ã®é
åã®ããã«ãè¤æ°ã®åãçµã¿åããã£ã¦æãç«ã£ã¦ããåã®ãã¨ã§ããã
è¤ååã¯ä»¥ä¸ã®éãã
-
é
å
-
é¢æ°
-
ãã¤ã³ã¿ã¼
-
ãªãã¡ã¬ã³ã¹
-
ã¯ã©ã¹
-
union
-
enum
-
éstaticãªã¯ã©ã¹ã®ã¡ã³ãã¼ã¸ã®ãã¤ã³ã¿ã¼
ãããã®è¤ååã¯ãå帰çã«é©ç¨ã§ãããä¾ãã°ãããåã¸ã®ãã¤ã³ã¿ã¼ãããåã¸ã®ãã¤ã³ã¿ã¼ã¸ã®ãã¤ã³ã¿ã¼ãããåã¸ã®ãã¤ã³ã¿ã¼ã¸ã®ãã¤ã³ã¿ã¼ã®é
åããªã©ã¨ãã£ãããã«ãæ§ç¯ãããåã®ãªãã¸ã§ã¯ãã®ãã¤ãæ°ããstd::size_tã§è¡¨ç¾å¯è½ãªç¯å²ãè¶
ããå ´åã¯ãã¨ã©ã¼ã¨ãªãã
voidã¸ã®ãã¤ã³ã¿ã¼ã¨ããªãã¸ã§ã¯ãåã¸ã®ãã¤ã³ã¿ã¼ãã²ã£ãããã¦ããªãã¸ã§ã¯ããã¤ã³ã¿ã¼å(object pointer type)ã¨å¼ã¶ã
ããåTã®ãªãã¸ã§ã¯ãã¸ã®ãã¤ã³ã¿ã¼ã®ãã¨ãããTåã¸ã®ãã¤ã³ã¿ã¼ãã¨ãããC++ã®è¦æ ¼ã®æé¢ã§åã«ããã¤ã³ã¿ã¼ãã¨ããå ´åãã¡ã³ãã¼ã¸ã®ãã¤ã³ã¿ã¼ã¯å«ã¾ãªãããã ããstaticã¡ã³ãã¼ã¸ã®ãã¤ã³ã¿ã¼ã¯ãã¡ã³ãã¼ã¸ã®ãã¤ã³ã¿ã¼ã§ã¯ãªãããã¤ã³ã¿ã¼ã«å«ã¾ãããã¨ã«æ³¨æã
ä¸å®å
¨ãªåã¸ã®ãã¤ã³ã¿ã¼ã¯ä½¿ãããããã®ãã¤ã³ã¿ã¼ã使ã£ã¦ã§ãããã¨ã¯å¶éãããã
ãªãã¸ã§ã¯ããã¤ã³ã¿ã¼åã®æå¹ãªå¤ã¯ãã¡ã¢ãªã¼ä¸ã®ãã1ãã¤ãã¸ã®ã¢ãã¬ã¹ã表ç¾ãã¦ããããnullãã¤ã³ã¿ã¼ã§ããããã¨ãã°ãTåã®ãªãã¸ã§ã¯ãããã¢ãã¬ã¹Aã«é
ç½®ããã¦ãã¦ãã¢ãã¬ã¹Aã®å¤ã¨ãªããã¤ã³ã¿ã¼ããã£ãå ´åããã®ãã¤ã³ã¿ã¼ã¯ããªãã¸ã§ã¯ããæã示ãã¦ããï¼ãã¤ã³ããã¦ããï¼ã¨å¼ã°ããã
ãã¤ã³ã¿ã¼åã®å¤ã®è¡¨ç¾æ¹æ³ã¯å®è£
ä¾åã§ãããã¬ã¤ã¢ã¦ãäºæãªåã¸ã®CV修飾ããããã¤ã³ã¿ã¼ã¨CV修飾ããã¦ããªããã¤ã³ã¿ã¼ã¯ãåãå¤è¡¨ç¾ã¨åãã¢ã©ã¤ã¡ã³ãè¦æ±ãæã¤ã
CV修飾ããã¦ããããCV修飾ããã¦ããªããvoidåã¸ã®ãã¤ã³ã¿ã¼ã¯ãåã®åãããªããªãã¸ã§ã¯ããæã示ãã®ã«ä½¿ããã¨ãã§ãããvoidåã¸ã®ãã¤ã³ã¿ã¼ã¯ç¹å¥ãªæ±ãã«ãªã£ã¦ãã¦ãã©ã®ãããªãªãã¸ã§ã¯ããã¤ã³ã¿ã¼ããä¿æã§ããã¨è¦å®ããã¦ãããcv void *åã®ãªãã¸ã§ã¯ãã¯ãcv char *ã¨åãå¤ã®è¡¨ç¾ã¨ã¢ã©ã¤ã¡ã³ãè¦æ±ãæã¤ã
è¤åå(Compound types)ã¨åºæ¬å(Fundamental types)ã§èª¬æããã¦ããåã¯ãCVé修飾å(cv-unqualified type)ã§ãããCVé修飾ãªå®å
¨åãä¸å®å
¨åãvoidã«ã¯ãä¸ç¨®é¡ã®CV修飾ãããåããããconst修飾ãããåãvolatile修飾ãããåãconst-volatile修飾ãããåã ã
-
constãªãã¸ã§ã¯ãã¨ã¯ããªãã¸ã§ã¯ãã®åããconst Tã¨ãªããããããã¯ãã®ãããªãªãã¸ã§ã¯ãã®ãµããªãã¸ã§ã¯ãã§ããã
-
volatileãªãã¸ã§ã¯ãã¨ã¯ããªãã¸ã§ã¯ãã®åããvolatile Tã¨ãªããããããã¯ãã®ãããªãªãã¸ã§ã¯ãã®ãµããªãã¸ã§ã¯ãã§ããã
-
const volatileãªãã¸ã§ã¯ãã¨ã¯ããªãã¸ã§ã¯ãã®åããconst volatile Tã¨ãªããããããã¯ãã®ãããªãªãã¸ã§ã¯ãã®ãµããªãã¸ã§ã¯ãã§ããã
ããåã®CV修飾ãããåã¨ãCVé修飾ã®åã¯ãç°ãªãåã§ããããã ããåã表ç¾ã¨ã¢ã©ã¤ã¡ã³ãè¦æ±ãæã¤ã
CV修飾åã«ã¯ãåé åºãåå¨ãããããã¯ãããCV修飾ããã¦ããåãæ¯è¼ãã¦æ±ºå®ã§ããã
ãã®é åºã¯ä»¥ä¸ã®éãã
CVé修飾 < const
CVé修飾 < volatile
CVé修飾 < const volatile
const < const volatile
volatile < const volatile
lvalueã¨rvalueã¨ããç¨èªã¯ãC++ã®ç¥å
ã§ããCè¨èªã®ãã®ã¾ãç¥å
ã§ãããBCPLã®é ãããæ
£ç¿çã«ä½¿ããã¦ããç¨èªã§ããããã®æ¬æ¥ã®æå³ã¯ã代å
¥å¼ã®å·¦å³ã®ãªãã©ã³ãã«è¨è¿°ãããã¨ãã§ããå¤ã¨ããæå³ã§ãã£ããlvalueã¯ä»£å
¥å¼ã®å·¦(left)ã«æ¸ããã¨ãã§ããå¤(value)ã§ãããããã¦ãleft valueã§ãããrvalueã¯å³(right)ã«æ¸ããã®ã§right valueã¨ãããã¨ã ã
int x ;
x = 0 ;
ãã®ä¾ã§ãxã¯ä»£å
¥å¼ã®å·¦è¾ºã«æ¸ããã®ã§lvalueã§ããã0ã¯å³è¾ºã«æ¸ããã®ã§rvalueã§ããã
ä»æ¥ã§ã¯ãlvalueã¨rvalueã¯ããã®æ¬æ¥ã®æå³ã失ããå
¨ãå¥ã®æå³ã§ä½¿ãããããã«ãªã£ã¦ãããå¼ã®å¤ãåé¡ããç¨èªã¨ãã¦ä½¿ããã¦ããã
C++11ã§ã¯ãå¼ã¯ãglvalueã¨rvalueã®äºç¨®é¡ã«åãããã¨ãã§ãããããã¯æ´ã«ç´°ååã§ããå¤ã¯ä¸ç¨®é¡ã®å¤ã«åé¡ãããã¨ãã§ãããlvalueã¨xvalueã¨prvalueã§ãããglvalueã¯lvalueã¨xvalueã«ç´°ååã§ãããrvalueã¯prvalueã¨xvalueã«ç´°ååã§ããã
åé¡åã®æå³ã¯ã以ä¸ã®ã¨ããã§ããã
lvalue
lvalueã¯ãé¢æ°ããªãã¸ã§ã¯ãã§ããã
lvalueã¯ãååä»ãã®å¤æ°ãæã示ããªãã¸ã§ã¯ããããã¤ã³ã¿ã¼ãçµç±ãã¦æã示ããªãã¸ã§ã¯ããªã©ã該å½ããã
lvalueã®ååã®ç±æ¥ã¯ãæ´å²ççµç·¯ã§left value(左辺å¤)ã§ããããC++ã§ã¯æ´å²ççµç·¯ã®æå³ã¨ã¯é¢ä¿ããªãã
xvalue
xvalueã¯ããªãã¸ã§ã¯ãã§ãããxvalueã®ãªãã¸ã§ã¯ãã¯å¤§æµããã®å¯¿å½ãè¿ããããããã¯å¯¿å½ã«é¢å¿ããªããã¨ã表ç¾ããããã«ä½¿ããããããã«ããããããªãã¸ã§ã¯ããxvalueã§ãããªãã°ãã ã¼ããã¦ãåé¡ã¯ãªãã¨ãããã¨ã表ç¾ããããã«ä½¿ãããã
xvalueã¯ãä¸é¨ã®å¼ã®çµæããrvalueãªãã¡ã¬ã³ã¹ã¸ã®æ示çãªãã£ã¹ããªã©ã該å½ããã
xvalueã®ååã®ç±æ¥ã¯ãeXpiring value(æ¶å¤±å¤)ã§ãããããã¯ãxvalueã¨ããã®ã¯å¯¿å½ãè¿ãã£ããã寿å½ã«é¢å¿ããªããæ¶å¤±ãã¦ãåé¡ã®ãªãå¤ã§ããã¨ããæå³ããåä»ããããã
glvalue
glvalueã¯ãlvalueã¨xvalueã®ç·ç§°ã§ããã
glvalueã®ååã®ç±æ¥ã¯ãgeneralized lvalue(ä¸è¬ålvalue)ã§ããã
rvalue
rvalueã¯ãxvalueã¨prvalueã®ç·ç§°ã§ãããxvalueã®ä»ã«ã¯ãä¸æãªãã¸ã§ã¯ããããªãã©ã«ã®å¤(123ã3.14ãtrueãªã©)ããç¹å®ã®ãªãã¸ã§ã¯ãã«é¢é£ä»ãããã¦ããªãå¤ãªã©ã該å½ããã
rvalueã®ååã®ç±æ¥ã¯ãæ´å²ççµç·¯ã§ãright value(å³è¾ºå¤)ã§ããããC++ã§ã¯æ´å²ççµç·¯ã®æå³ã¨ã¯é¢ä¿ããªãã
prvalue
prvalue(pure rvalue)ã¯ãrvalueã®ãã¡xvalueã§ã¯ãªããã®ã§ãããããã«ã¯ãä¸æãªãã¸ã§ã¯ãããªãã©ã«ã®å¤ããç¹å®ã®ãªãã¸ã§ã¯ãã«é¢é£ä»ãããã¦ããªãå¤ãªã©ã該å½ãããä¾ãã°ãé¢æ°å¼ã³åºãã®æ»ãå¤ã§ãåããªãã¡ã¬ã³ã¹ã§ã¯ãªããã®ãããã
C++03ã¾ã§ã¯ããªãã¡ã¬ã³ã¹ã¯ãåã«ããªãã¡ã¬ã³ã¹ãã¨å¼ã°ãã¦ãããC++11ã§ããlvalueãªãã¡ã¬ã³ã¹ãæå³ãããC++03ã®ãªãã¡ã¬ã³ã¹ã«ã¯ãrvalueã¯æç¸ã§ããªãã£ãã
int f() { return 0 ; }
int main()
{
int & lvalue_ref = f() ; // ã¨ã©ã¼
}
ãã ããconstãªlvalueãªãã¡ã¬ã³ã¹ã¯ãrvalueãæç¸ã§ããã¨ããä¾å¤çãªã«ã¼ã«ãããã
int f() { return 0 ; }
int main()
{
int const & lvalue_ref = f() ; // OK
}
C++ã«ã ã¼ãã®æ¦å¿µãæã¡è¾¼ãã«ããã£ã¦ãrvalueãéconstãªãªãã¡ã¬ã³ã¹ã§æç¸ãããã¨ããéè¦ãçã¾ããããã®ãããå¾æ¥ã®ãªãã¡ã¬ã³ã¹ããlvalueãªãã¡ã¬ã³ã¹ã¨ããæ°ããrvalueãªãã¡ã¬ã³ã¹ã追å ãããã¨ã«ãªã£ãã
int f() { return 0 ; }
int main()
{
int && lvalue_ref = f() ; // OK
}
rvalueãªãã¡ã¬ã³ã¹ã¯ãrvalueã®ã¿ãæç¸ã§ãããªãã¡ã¬ã³ã¹ã§ãããrvalueã§ãã以ä¸ã寿å½ãããã«å°½ãããããããã¯ãããã°ã©ãã¼ã¯ãã®ãªãã¸ã§ã¯ãã®å¯¿å½ã«é¢å¿ãæããªãã¨æ示çã«ææ表示ããã¨ã¿ãªããã¨ãã§ããã
ãã®ãããrvalueãªãã¡ã¬ã³ã¹ã§æç¸ã§ããã¨ãããã¨ã¯ããã®å¤ã®ä¿æããææ権ã横åããã¦ãåé¡ããªãã¨ãããã¨ã«ãªãã
class owner
{
private :
int * ptr ;
public :
owner( int value )
: ptr( new int( value ) )
{ }
// ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼
owner( owner const & lref )
: ptr( new int( *lref.ptr ) )
{ }
// ã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼
owner( owner && rref )
: ptr ( rref.ptr )
{
rref.ptr = nullptr ;
}
~owner( )
{
delete ptr ;
}
} ;
owner f()
{
return owner(123) ;
}
int main()
{
owner o = f() ;
}
rvalueãªãã¡ã¬ã³ã¹ã®å°å
¥ã«ãããã¹ãã¬ã¼ã¸ãªã©ã®ç¢ºä¿ã解æ¾ãå¿
è¦ãªãªã½ã¼ã¹ãããããã¯ãã¡ã¤ã«ãã¹ã¬ãããªã©ã®ã³ãã¼ã¨ããæ¦å¿µãåå¨ããªããªã½ã¼ã¹ã®ææ権ããã ã¼ã(移å)ãããã¨ãå¯è½ã«ãªã£ãã
ãã®ã³ãã¼ã¨å¯¾ããªãã ã¼ãã¨ããæ°ããæ¦å¿µã¯ãã ã¼ãã»ãã³ãã£ã¯ã¹(Move Semantics)ã¨å¼ã°ããããã°ã©ãã³ã°ææ³ã¨ãã¦ç¥ããã¦ãããããã°ã©ãã³ã°ææ³ã¯æ¬æ¸ã®ç¯çã§ã¯ãªãã®ã§ã詳ããã¯è§£èª¬ããªãã
ãªãã¸ã§ã¯ãåã«ã¯ãã¢ã©ã¤ã¡ã³ãè¦æ±(alignment requirements)ã¨ãããã®ãåå¨ãããããã¯ããªãã¸ã§ã¯ããæ§ç¯ãããã¹ãã¬ã¼ã¸ã®ã¢ãã¬ã¹ã«å¯¾ããå¶ç´ã§ããã
ã¢ã©ã¤ã¡ã³ã(alignment)ã¨ã¯ãã¡ã¢ãªä¸ã§é£ç¶ãããªãã¸ã§ã¯ããæ§ç¯ããã¨ãã®ã¢ãã¬ã¹ã®å¤ã«å¯¾ãããå®è£
ä¾åã®æ´æ°å¤ã§ããã
ã¢ã©ã¤ã¡ã³ãæå®åã使ããã¨ã«ãã£ã¦ãããå³æ ¼ãªã¢ã©ã¤ã¡ã³ããè¦æ±ãããã¨ãã§ããã詳細ã¯ã¢ã©ã¤ã¡ã³ãæå®åãåç
§ã
// ã¢ã©ã¤ã¡ã³ã8ãè¦æ±
alignas( 8 ) char[64] ;
alignofå¼ã使ããã¨ã«ãã£ã¦ãåã®ã¢ã©ã¤ã¡ã³ãè¦æ±ãå¾ããã¨ãã§ããã詳細ã¯alignofå¼ãåç
§ã
// intåã®ã¢ã©ã¤ã¡ã³ãè¦æ±ãåå¾
constexpr std::size_t align_of_int = alignof( int ) ;
以ä¸ã®ä¾ã¯ãé£ç¶ããã¡ã¢ãªä¸ã«ç¢ºä¿ãããäºã¤ã®intåã®ãªãã¸ã§ã¯ãã®å
é ã¢ãã¬ã¹ã表示ãã¦ãããçµæã¯å®è£
ã«ããç°ãªãã
#include <cstdio>
int main()
{
int ai[2] ;
std::printf(
"a[0]: %p\n"
"a[1]: %p",
&ai[0], &ai[1] ) ;
}
åºæ¬ã¢ã©ã¤ã¡ã³ã(fundamental alignment)ã¨ã¯ãå®è£
ãã©ã®ãããªæèã§ããµãã¼ããã¦ããã¢ã©ã¤ã¡ã³ãã®æ大å¤ã§ããããã®å¤ã¯ãalignof( std::max_align_t )ã«çããã
以ä¸ã®ä¾ã¯ãåºæ¬ã¢ã©ã¤ã¡ã³ãã®æ°å¤ãåºåããã³ã¼ãã§ãããçµæã¯å®è£
ã«ããç°ãªãã
#include <cstddef>
#include <iostream>
int main()
{
std::cout << "fundamental alignment is "
<< alignof( std::max_align_t )
<< std::endl ;
}
ããåã®ã¢ã©ã¤ã¡ã³ãè¦æ±ã¯ããã®åãå®å
¨ãªãªãã¸ã§ã¯ãã¨ãã¦ä½¿ããããããããã¯ãµããªãã¸ã§ã¯ãã¨ãã¦ä½¿ããããã§ãå¤ããå¯è½æ§ãããã
struct B { long double d ; } ;
struct D : virtual B { char c ; } ;
ãã¨ãã°ãä¸ã®ä¾ã®Dããå®å
¨ãªãªãã¸ã§ã¯ãã¨ãã¦ä½¿ã£ãå ´åããµããªãã¸ã§ã¯ãã¨ãã¦Bãå«ãã®ã§ãlong doubleã®ã¢ã©ã¤ã¡ã³ãè¦æ±ãèæ
®ãã¦ã¢ã©ã¤ã³ããããããããããDããå¥ã®ãªãã¸ã§ã¯ãã®ãµããªãã¸ã§ã¯ãã§ããããã®å¥ã®ãªãã¸ã§ã¯ãããBãvirtualåºæ¬ã¯ã©ã¹ã¨ãã¦æã¤å ´åã
D2 : virtual B, D { char c ; } ;
ããå®è£
ã§ã¯ãBã®ãµããªãã¸ã§ã¯ãã¯å¥ã®ãªãã¸ã§ã¯ãã®ãµããªãã¸ã§ã¯ãã¨ãªãããããããDã¯Bããµããªãã¸ã§ã¯ãã¨ãã¦æããªããããããªãããã®ãããªå ´åããµããªãã¸ã§ã¯ãã¨ãã¦ã®Dã®ã¢ã©ã¤ã¡ã³ãè¦æ±ã¯ãBã®ã¢ã©ã¤ã¡ã³ãè¦æ±ã«å½±é¿ãããªãããç¥ããªãã
ããã¯å®è£
ã«ãããalignofã®çµæã¯ããªãã©ã³ãã®åãå®å
¨ãªãªãã¸ã§ã¯ãã¨ãã¦ä½¿ãããå ´åã®ã¢ã©ã¤ã¡ã³ãè¦æ±ãè¿ãã
æ¡å¼µã¢ã©ã¤ã¡ã³ã(extended alignment)ã¯ãalignof( std::max_align_t )ããã大ããã¢ã©ã¤ã¡ã³ãã§ãããæ¡å¼µã¢ã©ã¤ã¡ã³ãããµãã¼ãããããã¯å®è£
ä¾åã§ãããã¾ãããµãã¼ããããã¨ãã¦ãããã¹ã¦ã®æèã§ãµãã¼ããããªããããããªãããããããæèã§æ¡å¼µã¢ã©ã¤ã¡ã³ãããµãã¼ããããªãå ´åãå®è£
ã¯ãã®ãããªã³ã¼ããã¨ã©ã¼ã«ããªããã°ãªããªãã
#include <cstddef>
void f()
{
// ãã®æèã§ãã®æ¡å¼µã¢ã©ã¤ã¡ã³ãããµãã¼ããããå ´åãOK
// ãµãã¼ããããªãå ´åãã¨ã©ã¼
alignas( alignof( std::max_align_t ) * 2 ) char buf[64];
}
æ¡å¼µã¢ã©ã¤ã¡ã³ããæã¤åã®ãã¨ããã¢ã©ã¤ã³è¶
éå(over-aligned type)ã¨ããã
// ã¢ã©ã¤ã³è¶
éåã®ä¾
struct
alignas( alignof( std::max_align_t ) * 2 )
S { } ;
// ãããã¢ã©ã¤ã³è¶
éå
struct S2
{
S s ;
} ;
ã¢ã©ã¤ã¡ã³ãã¯ãstd::size_tåã®å¤ã§è¡¨ç¾ãããã妥å½ãªã¢ã©ã¤ã¡ã³ãã¯ãalignofå¼ã§è¿ãããåºæ¬åã®ã¢ã©ã¤ã¡ã³ãã¨ãå®è£
ä¾åã®ã¢ã©ã¤ã¡ã³ãã§ãããå®è£
ä¾åã®ã¢ã©ã¤ã¡ã³ãã¯ãµãã¼ãããã¦ããªãå¯è½æ§ããããã¢ã©ã¤ã¡ã³ãã¯ãå¿
ããè² æ°ã§ã¯ãªã2ã®ä¹æ°ã§ãªããã°ãªããªãã1, 2, 4, 8, 16ã®ãããªæ°å¤ã¯ãå®è£
ããµãã¼ããã¦ããã°ã妥å½ãªã¢ã©ã¤ã¡ã³ãã§ããã3, 5, 6, 7, 9ã®ãããªæ°å¤ã¯ã妥å½ãªã¢ã©ã¤ã¡ã³ãã§ã¯ãªãã
ã¢ã©ã¤ã¡ã³ãã«ã¯ãé åºãããããã®é åºã¯ãä½ãæ¹ã¯ãããå¼±ãã(weaker)ã¢ã©ã¤ã¡ã³ãã¨ãããé«ãæ¹ã¯ãããå¼·ãã(stronger)ã¢ã©ã¤ã¡ã³ãã¨ãããããå³æ ¼ã(stricter)ãªã¢ã©ã¤ã¡ã³ãã¨ãããããå³æ ¼ãªã¢ã©ã¤ã¡ã³ãã¯ãã¢ã©ã¤ã¡ã³ãã®æ°å¤ã¨ãã¦ã®å¤ãé«ããããã¢ã©ã¤ã¡ã³ãè¦æ±ãæºããã¢ãã¬ã¹ã¯ããã®ã¢ã©ã¤ã¡ã³ãè¦æ±ããå¼±ãã¢ã©ã¤ã¡ã³ãè¦æ±ãæºããã
å®å
¨åã®ã¢ã©ã¤ã¡ã³ãè¦æ±ã¯ãalignofå¼ã®ãªãã©ã³ãã«åãä¸ãããã¨ã§åå¾ã§ããã
çãæåå(char, signed char, unsigned char)ã¯ããã£ã¨ãå¼±ãã¢ã©ã¤ã¡ã³ãè¦æ±ãæã¤ãããã«ãããçãæååããã¢ã©ã¤ã³ãããã¡ã¢ãªé åã®ããã®å
é¨åã¨ãã¦ä½¿ããã¨ãã§ããã
#include <new>
struct S
{
int i ;
double d ;
} ;
void f()
{
// Sãæ§ç¯ããã¡ã¢ãªé å
alignas(S) char buf [ sizeof(S) ] ;
// placement newã§Sãæ§ç¯
S * ptr = new( buf ) S ;
// çä¼¼ãã¹ãã©ã¯ã¿ã¼å¼ã³åºã
ptr->~S() ;
}
ã¢ã©ã¤ã¡ã³ãã¯æ¯è¼ãããã¨ãã§ãããã®çµæã¯å¸¸èçãªãã®ã§ããã
-
äºã¤ã®ã¢ã©ã¤ã¡ã³ãã®æ°å¤ãçããå ´åãã¢ã©ã¤ã¡ã³ãã¯çãã
-
äºã¤ã®ã¢ã©ã¤ã¡ã³ãã®æ°å¤ãç°ãªãå ´åãã¢ã©ã¤ã¡ã³ãã¯çãããªã
-
äºã¤ã®ã¢ã©ã¤ã¡ã³ãã®ãã¡ãæ°å¤ã®å¤§ããã»ãããããå³æ ¼ãªã¢ã©ã¤ã¡ã³ãã§ãã
æ¨æºã©ã¤ãã©ãªã«ã¯ããããã¡ã¼ä¸ã§æå®ãããã¢ã©ã¤ã¡ã³ãè¦æ±ãæºããã¢ãã¬ã¹ã®ãã¤ã³ã¿ã¼ãè¿ãã¨ããæå®ããã¢ã©ã¤ã¡ã³ãè¦æ±ãæºããã¢ãã¬ã¹ã®ã¹ãã¬ã¼ã¸ã確ä¿ããã©ã¤ãã©ãªããããæ¨æºã©ã¤ãã©ãªã¯æ¬æ¸ã®ç¯çã§ã¯ãªãã®ã§è§£èª¬ããªãã
ããããå®è£
ã§ãæ¡å¼µã¢ã©ã¤ã¡ã³ãããã®æèã§ãµãã¼ããããªãå ´åãããã°ã©ã ã¯ã¨ã©ã¼ã¨ãªããã¢ã©ã¤ã¡ã³ãè¦æ±ãæå®ãã¦åçã¹ãã¬ã¼ã¸ã確ä¿ããæ¨æºã©ã¤ãã©ãªã¯ãæå®ãããã¢ã©ã¤ã¡ã³ãã«å¾ããªãå ´åããã®æåã¯ç¢ºä¿å¤±æã«ãªãã
æ¨æºåå¤æï¼Standard conversionï¼ã¯ãæé»ã®åå¤æã¨ãå¼ã°ãã¦ãããC++ã«ã¯ãå¤ãã®çµã¿è¾¼ã¿åãããããç°ãªãåãªã®ã«ããããããããã£ã¹ãã使ãããæé»çã«åãå¤æã§ããå ´åãããããã®æ©è½ã®ãã¨ããæ¨æºåå¤æã¨ããã
short a = 0 ;
int b = a ; // shortããintã¸
long c = b ; // intããlongã¸
ãã®ä¾ã§ã¯ãshortããintã¸ãintããlongã¸ã¨ãåãå¤æãã¦ããããã¹ã¦ã®æ¨æºåå¤æãããã®ããã«åãããããã¦å®å
¨ã ã¨ã¯éããªãã
int a = 123456789 ;
float b = a ; // intããfloatã¸
b = 0.12345 ;
a = b ; // floatããintã¸
floatåããintåã§è¡¨ç¾ã§ããæ´æ°ã®æ¡ããã¹ã¦è¡¨ç¾ã§ããã¨ã¯éããªããintåã¯ãæ´æ°ã表ãåã§ããã®ã§ãå°æ°ç¹æ°ãæ£ãã表ç¾ãããã¨ã¯ã§ããªãããããæ´æ°ã¨æµ®åå°æ°ç¹æ°éã§ãå¤ãå®å
¨ã«è¡¨ç¾ã§ããªãå ´åãå®è£
ä¾åã®æ¹æ³ã§ãè¿ãå¤ã使ãããã
æ¨æºåå¤æã¯ã人éã«ã¨ã£ã¦ãã§ããã ãèªç¶ã«ãªãããã«ãè¨è¨ããã¦ããããããããã®æ¨æºåå¤æã¯ãCããåãç¶ãã ãæ´å²ã®ããæ±ãæ©è½ãªã®ã§ãã©ããã¦ããå®å
¨ã§ã¯ãªããããã§ã¯ãã©ã®ãããªæ¨æºåå¤æãããããã詳ãã説æããã
æ¬æ¸ã§ã¯ãæ®æ®µããæé»ã®åå¤æãã¨ç°¡åã«å¼ãã§ããæ¨æºåå¤æã«ãã©ã®ãããªãã®ãããã®ãã¨ãããã¨ãåããããã
æ¬æ¸ã§ã¯ãç
©éãé¿ããããã«çç¥ãã¦ããããå¤ãã®æ¨æºåå¤æã¯ãããåã®prvalueã®å¤ããå¥ã®åã®prvalueã®å¤ã«å¤æããããã«ãªã£ã¦ããããã®ãããæ¨æºåå¤æã®éã«ã¯ãå¿
è¦ãªå ´åãglvalueããèªåçã«prvalueã«å¤æããããããããlvalueããrvalueã¸ã®åå¤æã¨ãããå¤æã§ããglvalueã¯ãé¢æ°ã¨é
å以å¤ã§ããã
ãã®å¤æã¯ãé常ãã¾ãæèãããã¨ããªãã
é
åã¨ãã¤ã³ã¿ã¼ã¯ãããæ··åãããããã®çç±ã®ä¸ã¤ã«ãé
ååãããããããã¤ã³ã¿ã¼ã®ããã«æ¯èãã¨ãããã¨ãããã
int a[10] ;
// pã¯ãaã®å
é è¦ç´ ãæãã
int * p = a ;
// ã©ã¡ãããé
åaã®å
é è¦ç´ ã«0ã代å
¥ãã
*a = 0 ;
*p = 0 ;
ããã¯ãé
åãããã¤ã³ã¿ã¼ã¸ã®åå¤æã«ãããã®ã§ãããé
ååã¯ãé
åã®å
é è¦ç´ ã¸ã®ãã¤ã³ã¿ã¼ã¨ãã¦æ±ãããã
int a[10] ;
int * p1 = a ; // &a[0]ã¨åã
int (* p2 )[10] = &a ; // int [10]ã¸ã®ãã¤ã³ã¿ã¼
ããã§ãå¤æ°aã®åã¯ãint [10]ã§ãã£ã¦ãint *ã§ã¯ãªãããã ããint *ã«æé»ã®ãã¡ã«åå¤æãããã®ã§ããããããã¤ã³ã¿ã¼ã®ããã«æ¯èãã
å¤ãã®äººã¯ããããæé»ã®åå¤æã¨ãã¦ã¯æèãã¦ããªããé
åãããã¤ã³ã¿ã¼ã¸ã®åå¤æã¯ãé常ã«ãã使ãããå¤æã§ãã£ã¦ãå¤ãã®å¼ã§ã¯ãé
ååã¯ãèªåçã«ãé
åã®å
é è¦ç´ ã¸ã®ãã¤ã³ã¿ã¼ã«åå¤æãããã
é¢æ°ã®ååã¯ããã®é¢æ°ã¸ã®ãã¤ã³ã¿ã¼ã«åå¤æãããã
void f( void ) {}
int main()
{
// typeã¯é¢æ°ãã¤ã³ã¿ã¼ã®å
using type = void (*) (void) ;
// åãæå³ã
type p1 = f ;
type p2 = &f ;
}
fã®åã¯ãé¢æ°ã§ãã£ã¦ãé¢æ°ãã¤ã³ã¿ã¼ã§ã¯ãªããé¢æ°ãã¤ã³ã¿ã¼ã¨ã¯ã&fã§ãããããããé¢æ°ã¯ãæé»ã®ãã¡ã«ãé¢æ°ãã¤ã³ã¿ã¼ã«åå¤æãããã®ã§ãé¢æ°åfã¯ãé¢æ°ãã¤ã³ã¿ã¼ã¨ãã¦ã使ããã¨ãã§ããã
ãã®åå¤æããé常ã«ãã使ããããå¤ãã®å ´åã¯ãèªåçã«ãé¢æ°ã¯é¢æ°ãã¤ã³ã¿ã¼ã«å¤æãããã
ãã ãããã®åå¤æã¯ãéstaticãªã¡ã³ãã¼é¢æ°ã«ã¯é©ç¨ãããªãããã ããstaticãªã¡ã³ãã¼é¢æ°ã¯ããã®æ¨æºå¤æãé©ç¨ãããã
struct C
{
void f(void) {}
static void g(void) {}
} ;
// ã¨ã©ã¼
void ( C:: * error )(void) = C::f ;
// OK
void ( C::* ok )(void) = &C::f ;
// staticãªã¡ã³ãã¼é¢æ°ã¯ãæ®éã®é¢æ°ã¨åãããã«ãå¤æã§ãã
void (*ptr)(void) = C::g ;
void (*ptr2)(void) = &C::g ; // ãã ãããã¡ãã®æ¹ãåããããã
ãã®ãããªæé»ã®åå¤æãããã¨ã¯ãããé常ãé¢æ°ãã¤ã³ã¿ã¼ãæ±ãéã«ã¯ãæ示çã«åé
æ¼ç®åã§ãã&æ¼ç®åã使ã£ãã»ãããåãããããã
ããåTã¸ã®ãã¤ã³ã¿ã¼ã¯ãããconstã¾ãã¯volatileä»ãã®åTã¸ã®ãã¤ã³ã¿ã¼ã«å¤æã§ããã
int * p ;
int const * cp = p ;
int volatile * vp = p ;
int const volatile * cvp = p ;
cvp = cp ;
cvp = vp ;
ããã¯ãããå°ãªãCV修飾åã¸ã®ãã¤ã³ã¿ã¼ãããããå¤ãCV修飾åã¸ã®ãã¤ã³ã¿ã¼ã«ãæé»ã®ãã¡ã«åå¤æã§ããã¨ãããã¨ã§ããã
ãã ãããã¤ã³ã¿ã¼ã®ãã¤ã³ã¿ã¼ã®å ´åã¯ã注æãè¦ããã
int ** p ;
// ã¨ã©ã¼
int const ** cp = p ;
// ããã¯OK
int const * const * cp = p ;
ãªãããå®ã¯ããã®åå¤æãèªãã¦ãã¾ãã¨ãconstæ§ã«ç©´ã空ãã¦ãã¾ãã®ã ã
int main()
{
int const x = 0 ;
int * p ;
// ããã¯ã¨ã©ã¼ã
p = &x ;
// ãããããèªãããã¦ããã¨ããã
// å®éã¯ã¨ã©ã¼ã
int const ** cpp = &p ;
// cppãçµç±ãã¦ãpãæ¸ãæãããã¨ãã§ãã¦ãã¾ãã
*cpp = &x ;
// pã¯ãxãåç
§ã§ãã¦ãã¾ãã
*p = 0 ;
}
ãã®ãããããåãTã¨ããå ´åãT **ãããT const **ã¸ã®åå¤æã¯ãèªãããã¦ããªããT **ãããT const * const *ã¸ã®å¤æã¯ã§ããã
int * p = nullptr ;
int const * const * p2 = &p ; // OK
æ´æ°åã«ã¯ãå¤æé ä½ã¨ãããã®ãåå¨ãããããã¯ãæ¨æºåå¤æãããªã¹ãåæåã§èæ
®ããããæ´æ°åã®åªå
é ä½ã§ãããããã¯ãããã»ã©è¤éãªé ä½ã§ã¯ãªããåºæ¬çã«ã¯ãåã®ãµã¤ãºã®å¤§å°ã«ãã£ã¦æ±ºå®ãããããã£ã¨ããå¤ãã®å ´åãåã®ãµã¤ãºã¨ããã®ã¯ãå®è£
ä¾åãªã®ã ãã
åºæ¬çãªå¤æé ä½ã¯ã以ä¸ã®ããã«ãªãã
signed char < short int < int < long int < long long int
unsignedãªæ´æ°åã®é ä½ã¯ã対å¿ããsingedãªåã¨åãã§ããã
ãã®ä»ã«ããããã¤ãç´°ããã«ã¼ã«ãããã
charã¨signed charã¨ãunsigned charã¯ãåãé ä½ã§ããã
boolã¯ãæãä½ãé ä½ã¨ãªãã
char16_tãchar32_tãwchar_tã®é ä½ã¯ãå®è£
ãå²ãå½ã¦ãå
é¨çãªåã«ä¾åãããå¾ã£ã¦ããããã®å¤æé ä½ã¯ãå®è£
ä¾åã§ããã
æ¡å¼µæ´æ°åãã¤ã¾ããå®è£
ãç¬èªã«å®ç¾©ããæ´æ°åã¯ãå®è£
ä¾åã®é ä½ã«ãªãã
æ´æ°ã®ããã¢ã¼ã·ã§ã³ã¨ã¯ãå¤æé ä½ã®ä½ãåãããé«ãåã¸ãåå¤æãããã¨ã§ããããã ããåã«é ä½ãä½ãåããé«ãåã¸ã®åå¤æãªããä½ã§ãããã¨ããããã§ã¯ãªãã
bool, char16_t, char32_tãwchar_t以å¤ã®æ´æ°åã§ãintããå¤æé ä½ã®ä½ãæ´æ°åãã¤ã¾ããcharãshortããã®ä»ã®å®è£
ç¬èªã®æ¡å¼µæ´æ°åã¯ããããintåãããã®å¤ããã¹ã¦è¡¨ç¾ã§ããå ´åãintã«å¤æã§ããã
short s = 0 ;
int i = s ; // æ´æ°ã®ããã¢ã¼ã·ã§ã³
long l = s ; // ããã¯ãæ´æ°ã®åå¤æ
intããä½ãé ä½ã®æ´æ°åãããintåã¸ã®å¤æã¨ãããã¨ã«æ³¨æããªããã°ãªããªããlongãlong longã¸ã®å¤æãã¾ãã¯ãcharããshortã¸ã®å¤æãªã©ã¯ãããã¢ã¼ã·ã§ã³ã§ã¯ãªããæ´æ°ã®åå¤æã«åé¡ãããã
char16_tãchar32_tãwchar_tã¯ãå®è£
ã®é½åã«ããå
é¨çãªæ´æ°åã«å¤æã§ãããå
é¨çãªæ´æ°åã¨ããã®ã¯ãintãunsigned intãlong intãunsigned long intãlong long intãunsigned long long intã®ããããã§ãããããããããã®ã©ã®åã§ãããã¹ã¦ã®å¤ã表ç¾ã§ããªããªãã°ãå®è£
ä¾åã®æ´æ°åã«å¤æãããã¨ãã§ããã
ä»ãintåã§ãchar16_tã¨char32_tã®åããããã¹ã¦ã®å¤ã表ç¾ã§ãããã®ã¨ããã¨ã
char16_t c16 = u'ã' ;
char32_t c32 = U'ã' ;
wchar_t wc = L'ã' ;
int x = 0 ;
x = c16 ; // xã®å¤ã¯0x3042
x = c32 ; // xã®å¤ã¯0x3042
x = wc ; // xã®å¤ã¯å®è£
ä¾å
intåã¨wchar_tåã®ãµã¤ãºã¯ãå®è£
ã«ããç°ãªãã®ã§ããã®ã³ã¼ãã¯ãå®éã®C++ã®å®è£
ã§ã¯ãåãä¿è¨¼ã¯ãªãã
åºåºåãæå®ããã¦ããªãunscoped enumåã¯ãintãunsigned intãlong intãunsigned long intãlong long intãunsigned long long intã®ãã¡ãenumåã®ãã¹ã¦ã®å¤ã表ç¾ã§ããæåã®åã«å¤æã§ããããããã©ã®æ¨æºæ´æ°åã§ããã¹ã¦ã®å¤ã表ç¾ã§ããªãå ´åããã¹ã¦ã®å¤ã表ç¾ã§ããå®è£
ä¾åã®æ¡å¼µæ´æ°åã®ãã¡ããã£ã¨ãå¤æé ä½ã®ä½ãåãé¸ã°ããããããé ä½ã®åãæ´æ°åãäºã¤ããå ´åãã¤ã¾ããsignedã¨unsignedã¨ãéãå ´åãsignedãªæ´æ°åã®æ¹ãé¸ã°ããã
åºåºåãæå®ããã¦ãunscoped enumåã¯ãæå®ãããåºåºåã«å¤æã§ããããã®å ´åã§ãããã«æ´æ°ã®ããã¢ã¼ã·ã§ã³ãé©ç¨ã§ããå ´åããããã¢ã¼ã·ã§ã³ã¨ã¿ãªããããä¾ãã°ã
enum E : short { value } ;
short s = value ; // ããã¯æ´æ°ã®ããã¢ã¼ã·ã§ã³
int i = value ; // ãããæ´æ°ã®ããã¢ã¼ã·ã§ã³
ãã®ããã«ãenumã®å ´åã¯ãintå以å¤ã¸ã®å¤æã§ããããã¢ã¼ã·ã§ã³ã«ãªãã
intåã¸ã®ä»£å
¥ã§ã¯ãenumåããåºåºåã§ããshortã«å¤æãããå¾ãããã«intã«å¤æããã¦ãããããã¯ãã©ã¡ããããã¢ã¼ã·ã§ã³ã§ããã
ããããã£ã¼ã«ãã¯ããã¹ã¦ã®å¤ã表ç¾ã§ããå ´åãintã«å¤æã§ããã
struct A
{
int x:8 ;
} ;
int main()
{
A a = {0} ;
int x = a.x ; // æ´æ°ã®ããã¢ã¼ã·ã§ã³
}
ãããããããã£ã¼ã«ãã®å¤ããintãã大ããããunsigned intåã§è¡¨ç¾ã§ããå ´åã¯ãunsigned intã«å¤æã§ãããå¤ãunsigned intãã大ããå ´åã¯ãæ´æ°ã®ããã¢ã¼ã·ã§ã³ã¯è¡ãããªããæ´æ°ã®åå¤æãè¡ãããã
boolåã®å¤ã¯ãintåã«å¤æã§ãããfalseã¯0ã¨ãªããtrueã¯1ã¨ãªãã
int a = true ; // aã¯1
int b = false ; // bã¯0
以ä¸ããæ´æ°ã®ããã¢ã¼ã·ã§ã³ã§ãããããã«å½ã¦ã¯ã¾ããªãæ´æ°åå士ã®åå¤æã¯ããã¹ã¦ã次ã«è¿°ã¹ãæ´æ°ã®åå¤æã§ããã
æ´æ°åã¯ãä»ã®æ´æ°åã«åå¤æã§ãããã»ãã®ä¸ä¾ã示ãã¨ã
short s = 0 ;
int i = s ; // shortããintã¸ã®å¤æ
s = i ; // intããshortã¸ã®å¤æ
unsigned int ui = i ; // intããunsigned intã¸ã®å¤æ
i = ui ; // unsigned intããintã¸ã®å¤æ
long l = s ; // shortããlongã¸ã®å¤æ
long long ll = l ; // longããlong longã¸ã®å¤æã
æ´æ°ã®ããã¢ã¼ã·ã§ã³ä»¥å¤ã®æ´æ°ã®åå¤æã¯ããã¹ã¦ãæ´æ°ã®åå¤æã«ãªãããã®éãã¯ããªã¼ãã¼ãã¼ã解決ãªã©ã«å½±é¿ããã®ã§ãéè¦ã§ããã
æ´æ°ã®åå¤æã¯ãå±éºã§ãããå¤æå
ã®åããå¤æå
ã®å¤ã表ç¾ã§ããªãå ´åãããã
ä¾ãã°ãä»ãsigned charã¯8ãããã§ãintã¯16ãããã ã¨ä»®å®ããã
#include <limits>
int main()
{
int i = std::numeric_limits<signed char>::max() + 1 ;
signed char c = i ; // ã©ããªãï¼
}
signed charã¯ãintã®åãããå¤ããã¹ã¦è¡¨ç¾ã§ããããã§ã¯ãªãããã®å ´åãã©ããªã£ã¦ãã¾ãã®ãã
å¤æå
ã®æ´æ°åãunsignedã®å ´åãçµæã®å¤ã¯ãå¤æå
ã®å¯¾å¿ããä¸ä½æ¡ã®å¤ã§ããã
å
·ä½çãªä¾ã示ãã¦èª¬æããã
// unsigned charã8ããããunsigned intã16ãããã¨ãã
int main()
{
unsigned int ui = 1234 ;
unsigned char uc = ui ; // 210
}
ãã®å ´åãunsigned intåã¯ã16ããããuiã®å¤ã¯ã2é²æ°ã§0000010011010010ã§ãããunsigned charåã¯8ããããã¤ã¾ãããã®å ´åã®å¯¾å¿ããä¸ä½æ¡ã®å¤ã¯ã2é²æ°ã§11010010ï¼uiã®ä¸ä½8ãããï¼ã§ããããã£ã¦ãucã¯ã10é²æ°ã§210ã¨ãªãã
unsignedã®å ´åãå¤æå
ã®åããå¤æå
ã®å¤ã表ç¾ã§ããªãã¨ãã¦ãããã®å¤ãã©ããªããã ãã¯ãä¿è¨¼ããã¦ããããã£ã¨ããå¤ãå®å
¨ã«ä¿æã§ããªãã®ã§ãå±éºãªãã¨ã«ã¯å¤ãããªãã®ã ãã
å¤æå
ã®æ´æ°åãsignedã®å ´åã¯ãé常ã«å±éºã§ãããå¤æå
ã®æ´æ°åããå¤æå
ã®å¤ã表ç¾ã§ããå ´åãå¤ã¯å¤ãããªãã表ç¾ã§ããªãå ´åããã®å¤ã¯å®è£
ä¾åã§ããã
ä»ä»®ã«ãintåã¯ãsigned charåã®åãããå¤ããã¹ã¦è¡¨ç¾ã§ããããsigned charåã¯ãintåã®åãããå¤ããã¹ã¦è¡¨ç¾ãããã¨ã¯ã§ããªãã¨ãããã¾ããsigned charã¯8ããããintã¯16ãããã¨ãããsigned charã®æå°å¤ã¯-127ãæ大å¤ã¯127ãintã®æå°å¤ã¯-32767ãæ大å¤ã¯32767ã¨ããã
int main()
{
signed char c = 100 ;
int i = c ; // iã®å¤ã¯100
signed char value = 1000 ; // å¤ã¯å®è£
ä¾å
}
iã®å¤ã¯ã100ã§ããããªããªããä»ä»®å®ããç°å¢ã§ã¯ãintåã¯100ã表ç¾ã§ããããã§ãããvalueã®å¤ã¯ãå®è£
ä¾åã§ãããåãããªãããªããªãã°ãsigned charåã¯ã1000ã表ç¾ã§ããªãããã ããã®å ´åãå¤æå
ã®signedãªæ´æ°åã®å¤ã¯ãå®è£
ä¾åã§ããã
floatåã®å¤ã¯ãdoubleåã®å¤ã«å¤æã§ããããã®ã¨ããå¤ã¯å¤ãããªããã¤ã¾ããfloatããdoubleã¸ã®å¤æã¯ãã¾ã£ããåãå¤ã表ç¾ã§ãããã¨ãæå³ãã¦ããã
float f = 3.14 ;
double d = f ; // dã®å¤ã¯3.14
ãã®å¤æããæµ®åå°æ°ç¹æ°ã®ããã¢ã¼ã·ã§ã³ã¨ããã
æµ®åå°æ°ç¹æ°ã®ããã¢ã¼ã·ã§ã³ä»¥å¤ã®ãæµ®åå°æ°ç¹æ°å士ã®åå¤æããæµ®åå°æ°ç¹æ°ã®åå¤æã¨ããã
double d = 0.0 ;
float f = 0.0 ;
long double ld = 0.0 ;
f = d ; // doubleããfloatã¸ã®åå¤æ
ld = f ; // floatããlong doubleã¸ã®åå¤æ
ld = d ; // doubleããlong doubleã¸ã®åå¤æ
ãããå¤æå
ã®åããå¤æå
ã®åã®å¤ãããã¹ã¦è¡¨ç¾ã§ããã®ãªãã°ãå¤ã¯å¤ãããªããå¤ãæ£ç¢ºã«è¡¨ç¾ã§ããªãå ´åã¯ãæãè¿ãå¤ãé¸ã°ããããã®è¿ä¼¼å¤ãã©ã®ããã«é¸ã°ãããã¯ãå®è£
ä¾åã§ãããè¿ä¼¼å¤ãã表ç¾ã§ããªãå ´åã®æåã¯ãæªå®ç¾©ã§ããã
æµ®åå°æ°ç¹æ°åã¯ãæ´æ°åã«å¤æã§ããããã®ã¨ããå°æ°é¨åã¯åãæ¨ã¦ããããå°æ°é¨åãåãæ¨ã¦ãå¾ã®å¤ããå¤æå
ã®æ´æ°åã§è¡¨ç¾ã§ããªãå ´åãæåã¯æªå®ç¾©ã§ããã
int x = 1.9 ; // xã®å¤ã¯ã1
int y = 1.9999 ; // yã®å¤ã¯ã1
int z = 0.9999 ; // zã®å¤ã¯ã0
æ´æ°åããããã¯unscoped enumåã¯ãæµ®åå°æ°ç¹æ°åã«å¤æã§ãããçµæã¯ãå¯è½ã§ããã°ãã¾ã£ããåãå¤ã«ãªããè¿ä¼¼å¤ã§è¡¨ç¾ã§ããå ´åãå®è£
ä¾åã®æ¹æ³ã«ãã£ã¦ãè¿ä¼¼å¤ãé¸ã°ãããå¤ã表ç¾ã§ããªãå ´åã®æåã¯ãæªå®ç¾©ã§ããã
float f = 1 ; // fã®å¤ã¯ã1.0f
nullãã¤ã³ã¿ã¼å®æ°ã¨ã¯ãæ´æ°åå®æ°ã§ã0ã§ãããã®ããstd::nullptr_tåã§ããã
0 ; // nullãã¤ã³ã¿ã¼å®æ°
1 ; // ããã¯nullãã¤ã³ã¿ã¼å®æ°ã§ã¯ãªã
nullptr ; // nullãã¤ã³ã¿ã¼å®æ°ãåã¯std::nullptr_t
0ãnullãã¤ã³ã¿ã¼å®æ°ã¨ãã¦æ±ãããã®ã¯ãæ´å²çãªçç±ã§ããã
nullãã¤ã³ã¿ã¼å®æ°ã¯ãã©ããªãã¤ã³ã¿ã¼åã«ã§ãå¤æã§ããããã®å¤ããnullãã¤ã³ã¿ã¼å¤ï¼null pointer valueï¼ã¨ãããnullãã¤ã³ã¿ã¼å®æ°å士ãæ¯è¼ããã¨ãçããã¨è©ä¾¡ãããã
int * a = nullptr ;
char * c = nullptr ;
int ** pp = nullptr ;
bool b = (nullptr == nullptr) ; // true
nullãã¤ã³ã¿ã¼å®æ°ããCV修飾ä»ãã®åã¸ã®ãã¤ã³ã¿ã¼ã«å¤æããå ´åããã®ãã¤ã³ã¿ã¼ã®åå¤æã®ã¿ãè¡ããããCV修飾åã®åå¤æã§ã¯ãªãã
// ãã¤ã³ã¿ã¼ã®åå¤æã®ã¿ãè¡ãããã
// CV修飾åã®åå¤æã¯è¡ãããªãã
int const * p = nullptr ;
æ´æ°åå®æ°ã®nullãã¤ã³ã¿ã¼å®æ°ã¯ãstd::nullptr_tåã«å¤æã§ãããçµæã®å¤ã¯ãnullãã¤ã³ã¿ã¼ã§ããã
std::nullptr_t null = 0 ;
ãããªãã¸ã§ã¯ãã¸ã®ãã¤ã³ã¿ã¼åã¯ãvoidã¸ã®ãã¤ã³ã¿ã¼ã«å¤æã§ããã
int x = 0 ;
int * int_pointer = &x ;
void * void_pointer = int_pointer ; // int *ããvoid *ã«å¤æã§ãã
ãã®æãCV修飾åãä»ãã¦ããå ´åãæ¶ããã¨ã¯ã§ããªãã
int x = 0 ;
int const * int_pointer = &x ;
void * error = int_pointer ; // ã¨ã©ã¼
void const * ok = int_pointer ; // OK
void *ã«å¤æããå ´åããã¤ã³ã¿ã¼ã®å¤ã¯ãå¤æå
ã®ãªãã¸ã§ã¯ãã®ã¹ãã¬ã¼ã¸ã®ãå
é ãæã示ããå¤ãnullãã¤ã³ã¿ã¼ã®å ´åã¯ãå¤æå
ã®åã®nullãã¤ã³ã¿ã¼ã«ãªãã
æ´¾çã¯ã©ã¹ã®ãã¤ã³ã¿ã¼ãããåºæ¬ã¯ã©ã¹ã®ãã¤ã³ã¿ã¼ã«å¤æãããã¨ãã§ããã
struct Base { } ;
struct Derived : Base { } ;
Derived * p = nullptr ;
Base * bp = p ; // OKãDerived *ããBase *ã¸ã®å¤æ
ãããåºæ¬ã¯ã©ã¹ã«ã¢ã¯ã»ã¹åºæ¥ãªãå ´åããææ§ãªå ´åã¯ãã¨ã©ã¼ã¨ãªãã
// åºæ¬ã¯ã©ã¹ã«ã¢ã¯ã»ã¹åºæ¥ãªãå ´å
struct Base { } ;
struct Derived : private Base { } ;
Derived * d = nullptr ;
Base * b = d ; // ã¨ã©ã¼ãBaseã«ã¯ã¢ã¯ã»ã¹åºæ¥ãªãã®ã§ãå¤æã§ããªã
// ææ§ãªå ´å
struct Base { } ;
struct Wrap1 : Base { } ;
struct Wrap2 : Base { } ;
// Derivedã¯ãåºæ¬ã¯ã©ã¹ã¨ãã¦ãµãã¤ã®Baseãæã£ã¦ããã
struct Derived : Wrap1, Wrap2 { } ;
Derived * ptr = nullptr ;
// ã¨ã©ã¼
// Wrap1::Baseã¨ãWrap2::Baseã®ã©ã¡ããªã®ããææ§
Base * ambiguous_base = ptr ;
// OK
// Wrap1::Base
Base * Wrap1_base = static_cast<Wrap1 *>(ptr) ;
æ´¾çã¯ã©ã¹ã®ãã¤ã³ã¿ã¼ããåºæ¬ã¯ã©ã¹ãã¤ã³ã¿ã¼ã¸ã®å¤æã®çµæã¯ãæ´¾çã¯ã©ã¹ã®ä¸ã®ãåºæ¬ã¯ã©ã¹é¨åãæããããã¯ãå¤æã®çµæããã¤ã³ã¿ã¼ã®å¤ãå¤ããå¯è½æ§ããããå®è£
ã«ä¾åããã®ã§ããã¾ãå
·ä½çãªä¾ãæãããã¯ãªãããä¾ãã°ã以ä¸ã®ãããªã³ã¼ãã¯ãå¤ãã®å®è£
ã§ããã¤ã³ã¿ã¼ã®å¤ãå¤ããã
#include <cstdio>
struct Base1 { int x ; } ;
struct Base2 { int x ; } ;
struct Derived : Base1, Base2 { } ;
int main()
{
Derived d ;
// dã¸ã®ãã¤ã³ã¿ã¼
Derived * d_ptr = &d ;
std::printf("d_ptr : %p\n", d_ptr) ;
// åºæ¬ã¯ã©ã¹ã®ãã¤ã³ã¿ã¼ã¸åå¤æ
Base1 * b1_ptr = d_ptr ;
Base2 * b2_ptr = d_ptr ;
// å¤ãã®å®è£
ã§ã¯ã
// b1_ptrã¨b2_ptrã®ã©ã¡ããããd_ptrã¨åãå¤ã§ã¯ãªãã
std::printf("b1_ptr : %p\n", b1_ptr) ;
std::printf("b2_ptr : %p\n", b2_ptr) ;
// æ´¾çã¯ã©ã¹ã¸ãã£ã¹ãï¼æ¨æºåå¤æã®éå¤æï¼
Derived * d_ptr_from_b1 = static_cast<Derived *>(b1_ptr) ;
Derived * d_ptr_from_b2 = static_cast<Derived *>(b2_ptr) ;
// å¤ãã®å®è£
ã§ã¯ã
// d_ptrã¨åãå¤ã«ãªãã
std::printf("d_ptr_from_b1 : %p\n", d_ptr_from_b1) ;
std::printf("d_ptr_from_b2 : %p\n", d_ptr_from_b1) ;
}
ãã®ããã«ãåºæ¬ã¯ã©ã¹ã¨æ´¾çã¯ã©ã¹ã®éã®ãã¤ã³ã¿ã¼ã®ãã£ã¹ãã¯ããã¤ã³ã¿ã¼ã®å¤ã®å¤ããå¯è½æ§ãããããã®ãããªåå¤æã«ã¯ãåã«å¤ããã®ã¾ã¾ä½¿ããreinterpret_castã¯ä½¿ããªãã
å¤æå
ã®ãã¤ã³ã¿ã¼ã®å¤ãnullãã¤ã³ã¿ã¼ã®å ´åã¯ãå¤æå
ã®åã®nullãã¤ã³ã¿ã¼ã«ãªãã
nullãã¤ã³ã¿ã¼å®æ°ã¯ãã¡ã³ãã¼ã¸ã®ãã¤ã³ã¿ã¼ã«ãå¤æã§ãããå¤æãããçµæã®å¤ããnullã¡ã³ãã¼ãã¤ã³ã¿ã¼å¤ï¼null member pointer valueï¼ã¨ããã
struct C { int data ; } ;
int C::* ptr = nullptr ;
nullã¡ã³ãã¼ãã¤ã³ã¿ã¼å¤ã¯ãä»ã®ã¡ã³ãã¼ã¸ã®ãã¤ã³ã¿ã¼ã®å¤ã¨æ¯è¼ã§ããã
struct C { int data ; } ;
int C::* ptr1 = nullptr ;
int C::* ptr2 = &C::data ;
bool b = ( ptr1 == ptr2 ) ; // false
æ´æ°ãæµ®åå°æ°ç¹æ°ãunscoped enumããã¤ã³ã¿ã¼ãã¡ã³ãã¼ã¸ã®ãã¤ã³ã¿ã¼ã¯ãboolã«å¤æã§ãããã¼ãå¤ãnullãã¤ã³ã¿ã¼å¤ãnullã¡ã³ãã¼ãã¤ã³ã¿ã¼å¤ã¯ãfalseã«å¤æãããããã以å¤ã®å¤ã¯ãã¹ã¦ãtrueã«å¤æãããã
bool b1 = 0 ; // false
bool b2 = 1 ; // true
bool b3 = -1 ; // true
bool b4 = nullptr ; // false
int x = 0 ;
bool b5 = &x ; // true
å¼ï¼expressionï¼ã¨ã¯ãæ¼ç®åï¼operatorï¼ã¨ãªãã©ã³ãï¼operandï¼ãçµã¿åããããã®ã§ããããªãã©ã³ãã¨ã¯ãè¨ãã°ãæ¼ç®åãé©ç¨ããå¼æ°ã§ãããå¼ã¯ãä½ããã®æåãããçµæãè¿ããå¼ã®çµæã¯ãlvalueãxvalueãprvalueã«ãªãã
// æ¼ç®åã¯+
// ãªãã©ã³ãã¯1ã¨2
1 + 2 ;
çµã¿è¾¼ã¿å以å¤ã®åã«å¯¾ãã¦ã¯ãæ¼ç®åã¯ãªã¼ãã¼ãã¼ãããã¦ããå¯è½æ§ãããããã®å ´åã®æåã«ä»ãã¦ã¯ããªã¼ãã¼ãã¼ãé¢æ°æ¬¡ç¬¬ã§ããã
å¼ãè©ä¾¡ããéãçµæãæ°å¦çã«å®ç¾©ããã¦ããªãå ´åããåã®è¡¨ç¾ã§ããç¯å²ãè¶
ããå ´åã®æåã¯ãæªå®ç¾©ã§ãããæ°å¦çã«å®ç¾©ããã¦ããªãå ´åã¨ããã®ã¯ãä¾ãã°ã¼ãé¤ç®ãããã
å¤ãã®äºé
æ¼ç®åã¯ãæ°å¤åãenumããªãã©ã³ãã«åãããã®æãäºã¤ã®ãªãã©ã³ãã®åããããããéãå ´åãåå¤æãè¡ãããããã®åå¤æã®ã«ã¼ã«ã¯ã以ä¸ã®ããã«ãªãã
ãªãã©ã³ãã«scoped enumåãããå ´åãå¤æã¯è¡ãããªããããçæ¹ã®ãªãã©ã³ãããåãåã§ãªãå ´åã¯ãã¨ã©ã¼ã«ãªãããã ã
çæ¹ã®ãªãã©ã³ããæµ®åå°æ°ç¹æ°åã®å ´åãããçæ¹ã®ãªãã©ã³ãã¯ããã®æµ®åå°æ°ç¹æ°åã«å¤æããããæµ®åå°æ°ç¹æ°åã®éã®åªå
é ä½ã¯ãlong double > double > floatã§ããã
// ãªãã©ã³ãã¯ãlong doubleã¨double
// long doubleã«å¤æããã
1.0l + 1.0 ;
1.0 + 1.0l ;
// ãªãã©ã³ãã¯ãdoubleã¨int
// doubleã«å¤æããã
1.0 + 1 ;
1 + 1.0 ;
ãªãã©ã³ããæµ®åå°æ°ç¹æ°åã§ã¯ãªãå ´åãã¤ã¾ããæ´æ°åããunscoped enumåã®å ´åãã¾ãã両æ¹ã®ãªãã©ã³ãã«å¯¾ãã¦ãæ´æ°ã®ããã¢ã¼ã·ã§ã³ãé©ç¨ããããã¤ã¾ããintåããå¤æé ä½ã®ä½ãåã¯ãintåã«å¤æãããããªãã©ã³ããunsignedãªæ´æ°åã®å ´åã¯ãunsigned intã«å¤æãããããã®å¾ã両æ¹ã®ãªãã©ã³ãã®ãã¡ãå¤æé ä½ãé«ãæ¹ã®åã«åãããããã
short s = 0 ;
auto type = s + s ;
ãã®å ´åããªãã©ã³ãã§ããsã¯ã両æ¹ã¨ããintåã«å¤æãããããã®çµæã両æ¹ã®ãªãã©ã³ãã¯åãåã«ãªãã®ã§ãçµæã®åã¯intã«ãªãã
short s = 0 ;
long l = 0 ;
auto type2 = l + s ;
ãã®å ´åãsã¯ã¾ãintåã«å¤æããããlongã¨intã§ã¯ãlongã®æ¹ããå¤æé ä½ãé«ãã®ã§ãçµæã®åã¯longã«ãªãã
ãã®æã符å·ã®éãæ´æ°åããªãã©ã³ãã«ãªãã¨ãé常ã«è¤éãªå¤æãè¡ãããããæ¬æ¸ã§ã¯è§£èª¬ããªãã
å¼ã«ã¯ãåªå
é ä½ã¨è©ä¾¡é åºãããã
åªå
é ä½ã¨ã¯ãããå¼ã®ä¸ã§ãç°ãªãå¼ãè¤æ°ä½¿ãããå ´åãã©ã¡ããå
ã«è©ä¾¡ãããã®ãã¨ããé ä½ã§ããããã®åªå
é ä½ã¯ã人éã«ã¨ã£ã¦èªç¶ã«ãªãããã«è¨è¨ããã¦ããã®ã§ãé常ãå¼ã®åªå
é ä½ãæ°ã«ããå¿
è¦ã¯ãªãã
// 1 + (2 * 3)
// operator *ãåªå
ããã
1 + 2 * 3 ;
int x ;
// operator +ãåªå
ããã
x = 1 + 1 ;
è©ä¾¡é åºã¨ã¯ãããå¼ã®ä¸ã§ãåªå
é ä½ã®åãå¼ãè¤æ°ä½¿ãããå ´åãã©ã¡ããå
ã«è©ä¾¡ãããã¨ããé åºã§ãããããã¯ãå¼ãã¨ã«ããå·¦ããå³ï¼Left-To-Rightï¼ãããããã¯ãå³ããå·¦ï¼Right-To-Leftï¼ãã®ã©ã¡ããã«ãªãã
ãã¨ãã°ãoperator +ã¯ããå·¦ããå³ãã§ããã
// (1 + 1) + 1 ã¨åã
1 + 1 + 1 ;
ä¸æ¹ãoperator = ã¯ããå³ããå·¦ãã§ããã
int x ; int y ;
// x = (y = 0) ã¨åã
x = y = 0 ;
ãããã人éã«ã¨ã£ã¦èªç¶ã«ãªãããã«è¨è¨ããã¦ãããé常ãæ°ã«ããå¿
è¦ã¯ãªãã
typeidæ¼ç®åãsizeofæ¼ç®åãnoexceptæ¼ç®åãdecltypeåæå®åã§ã¯ããããã¯æªè©ä¾¡ãªãã©ã³ãï¼unevaluated operandï¼ã¨ãããã®ã使ãããããã®ãªãã©ã³ãã¯æåéããè©ä¾¡ãããªãå¼ã§ããã
ãªãã©ã³ãã®å¼ã¯è©ä¾¡ãããªãããå¼ãè©ä¾¡ããçµæã®åã¯ãé常ã®è©ä¾¡ãããå¼ã¨ä½ãå¤ãããªãã
int f()
{
std::cout << "hello" << std::endl ;
return 0 ;
}
int main()
{
// int x ; ã¨åç
// é¢æ°fã¯å¼ã°ããªã
decltype( f() ) x ;
}
ãã®ä¾ã§ã¯ããªãã©ã³ãã®å¼ã®çµæã®åããå¤æ°xã¨ãã¦å®£è¨ãå®ç¾©ãã¦ãããé¢æ°å¼ã³åºãã®çµæã®åã¯ãé¢æ°ã®æ»ãå¤ã®åã«ãªãã®ã§ãåã¯intã§ããããã ããå¼èªä½ã¯è©ä¾¡ãããªãã®ã§ãå®è¡æã«é¢æ°ãå¼ã°ãããã¨ã¯ãªããã¤ã¾ããæ¨æºåºåã«helloã¨åºåããããã¨ã¯ãªãã
ãã®æªè©ä¾¡å¼ã¯ãè©ä¾¡ãããªãã¨ãããã¨ãé¤ãã°ãé常ã®å¼ã¨å
¨ãåãããã«æ±ããããä¾ãã°ããªã¼ãã¼ãã¼ã解決ããã³ãã¬ã¼ãã®ã¤ã³ã¹ã¿ã³ã¹åãªã©ããé常ã®å¼ã¨åãããã«åãã
// é¢æ°ã®å®£è¨ã ãã§ãããå®ç¾©ã¯å¿
è¦ãªã
double f(int) ;
int f(double) ;
int main()
{
// double x ; ã¨åç
decltype( f(0) ) x ;
// int y ; ã¨åç
decltype( f(0.0) ) y ;
}
ãã®ä¾ã§ã¯ãé¢æ°fã¯ã宣è¨ã ãããã¦ãã¦ãå®ç¾©ããªããããããããã¯å
¨ãåé¡ããªãããªããªãã°ãæªè©ä¾¡å¼ã¯è©ä¾¡ãããªãã®ã§ãé¢æ°fãå¼ã°ãããã¨ã¯ãªããå¼ã°ãããã¨ããªããã°ãå®ç¾©ãå¿
è¦ã¯ãªãã
ä¸æ¬¡å¼ã«ã¯ãå¤ãã®ç´°ããªç¨®é¡ããããä¾ãã°ããªãã©ã«ãååãä¸æ¬¡å¼ã§ãããããã§ã¯ãä¸æ¬¡å¼ã®ä¸ã§ããç¹ã«éè¦ãªãã®ã説æããã
:: æ¼ç®åã¯ãããååã®ã¹ã³ã¼ããæå®ããæ¼ç®åã§ããããã®ãããéå
¬å¼ã«ãã¹ã³ã¼ã解決æ¼ç®åãã¨ãå¼ã°ãã¦ãããããããå
¬å¼ã®ååã¯ã:: æ¼ç®å(operator ::)ã§ããã::ã«ç¶ãååã®ã¹ã³ã¼ãã¯ã::ã®åã«æå®ãããã¹ã³ã¼ãã«ãªãã
// ã¹ã³ã¼ãã¯ã°ãã¼ãã«
int x = 0;
// ã¹ã³ã¼ãã¯NSåå空é
namespace NS { int x = 0; }
// ã¹ã³ã¼ãã¯Cã¯ã©ã¹
struct C { static int x ; } ;
int C::x = 0 ;
int main()
{ // ã¹ã³ã¼ãã¯main()é¢æ°ã®ãããã¯
int x = 0 ;
x ; // ãããã¯
::x ; // ã°ãã¼ãã«
NS::x ; // NSåå空é
C::x ; // ã¯ã©ã¹
}
ãã®ããã«ã::ã«ç¶ãååã®ã¹ã³ã¼ããæå®ãããã¨ãã§ãããã¹ã³ã¼ããçç¥ãããå ´åã¯ãã°ãã¼ãã«ã¹ã³ã¼ãã«ãªãã
å¼ã®çµæã¯ã::ã«ç¶ãååããé¢æ°ãå¤æ°ã®å ´åã¯lvalueã«ããã以å¤ã¯prvalueã«ãªãã
æ¬å¼§å¼ã¨ã¯ãæ¬å¼§ã§ãããããã¯ãå¼ãå²ããã¨ãã§ãããæ¬å¼§å¼ã®çµæã¯ãæ¬å¼§ã®ä¸ã®å¼ã¨ã¾ã£ããåãã«ãªããããã¯ä¸»ã«ãã²ã¨ã¤ã®å¼ã®ä¸ã§ãè©ä¾¡ããé åºãæå®ãããããªå ´åã«ç¨ããããããããã¯ãåã«ã³ã¼ããåãããããã強調ããããã«ä½¿ã£ã¦ãæ§ããªãã
(0) ; // æ¬å¼§å¼
// 1 + (2 * 3) = 1 + 6 = 7
1 + 2 * 3 ;
// 3 * 3 = 9
(1 + 2 ) * 3
ã»ã¨ãã©ã®å ´åãæ¬å¼§å¼ã®æç¡ã¯ãæ¬å¼§ã®ä¸ã®å¼ã®çµæã«å½±é¿ãä¸ããªãããã ããæ¬å¼§å¼ã®æç¡ã«ãã£ã¦æå³ãå¤ããå ´åããããä¾ãã°ãdecltypeæå®åã ã
ã©ã ãå¼ï¼lambda expressionï¼ã¯ãé¢æ°ãªãã¸ã§ã¯ããç°¡åã«è¨è¿°ããããã®å¼ã§ããã以ä¸ã®ãããªææ³ã«ãªãã
[ ã©ã ããã£ããã£ã¼opt ] ( ä»®å¼æ° ) mutableopt ä¾å¤æå®opt -> æ»ãå¤ã®åopt
ã©ã ãå¼ããé常ã®é¢æ°ã®ããã«ä½¿ãæ¹æ³ã説æãããã¾ããã©ã ãå¼ã®æ§é ã¯ã以ä¸ã®ããã«ãªã£ã¦ããã
[ /*ã©ã ããã£ããã£ã¼*/ ] // ã©ã ãå°å
¥å
( /*ä»®å¼æ°ãªã¹ã*/ ) // çç¥å¯è½
-> void // æ»ãå¤ã®åãçç¥å¯è½
{} // è¤åæ
ããããé常ã®é¢æ°å®ç¾©ã¨æ¯è¼ãã¦ã¿ãã
auto // é¢æ°å®£è¨
func // é¢æ°å
() // å¼æ°ãªã¹ã
-> void // æ»ãå¤ã®å
{} // é¢æ°ã®å®ç¾©
ã©ã ãå¼ã¯ãé¢æ°ãªãã¸ã§ã¯ãã§ãããé常ã®é¢æ°ã®ããã«ãå¼æ°ãããã°ãæ»ãå¤ãããããã¡ãããé常ã®é¢æ°ã®ããã«ãä½ãå¼æ°ã«åããªããã¨ãã§ããããæ»ãå¤ãè¿ããªããã¨ãã§ããã
// é常ã®é¢æ°
auto f() -> void {}
// ã©ã ãå¼
[]() -> void {} ;
ã©ã ãå¼ãè©ä¾¡ããçµæã¯ãprvalueã®ä¸æãªãã¸ã§ã¯ãã«ãªãããã®ä¸æãªãã¸ã§ã¯ãããã¯ãã¼ã¸ã£ã¼ãªãã¸ã§ã¯ãï¼closure objectï¼ã¨å¼ã¶ãã¯ãã¼ã¸ã£ã¼ãªãã¸ã§ã¯ãã®åã¯ãã¯ãã¼ã¸ã£ã¼åï¼closure typeï¼ã§ãããã¯ãã¼ã¸ã£ã¼åã¯ã¦ãã¼ã¯ã§ãååããªããããã¯å®è£
ä¾åã®åã§ãããã¦ã¼ã¶ã¼ã¯å
·ä½çãªåãç¥ããã¨ãã§ããªãããã®ã¯ãã¼ã¸ã£ã¼ãªãã¸ã§ã¯ãã¯ãé¢æ°ãªãã¸ã§ã¯ãã¨åãããã«æ¯èãã
auto f = []() ->void {} ;
ã©ã ãå¼ã¯é¢æ°ãªãã¸ã§ã¯ããªã®ã§ãé常ã®é¢æ°ã¨åãããã«ãoperator ()ãé©ç¨ãããã¨ã§å¼ã³åºããã¨ãã§ããã
// é常ã®é¢æ°
auto f() -> void {}
int main()
{
f() ; // é¢æ°ã®å¼ã³åºã
// ã©ã ãå¼
auto g = []() -> void {} ;
g() ; // ã©ã ãå¼ã®å¼ã³åºã
// ã©ã ãå¼ãç´æ¥å¼ã³åºã
[]() -> void {}() ;
}
ä»®å¼æ°ãªã¹ãã¨ãæ»ãå¤ã®åã¯ãçç¥ã§ãããå¾ã£ã¦ãæå°ã®ã©ã ãå¼ã¯ã以ä¸ã®éãã«ãªãã
[]{}
ä»®å¼æ°ãªã¹ããçç¥ããå ´åã¯ãå¼æ°ãåããªãã¨ãããã¨ãæå³ãããæ»ãå¤ã®åãçç¥ããå ´åã¯ãã©ã ãå¼ã®è¤åæã®å
容ã«ãã£ã¦ãæ»ãå¤ã®åãæ¨æ¸¬ããããè¤åæã以ä¸ã®å½¢ã«ãªã£ã¦ããå ´åã
{ return å¼ ; }
æ»ãå¤ã®åã¯ãå¼ã« lvalueããrvalueã¸ã®åå¤æã é
åãããã¤ã³ã¿ã¼ã¸ã®åå¤æãé¢æ°ãããã¤ã³ã¿ã¼ã¸ã®åå¤æãé©ç¨ããçµæã®åã«ãªãã
ãã以å¤ã®å ´åã¯ãvoidåã«ãªãã
注æããªããã°ãªããªããã¨ã¯ãæ»ãå¤ã®åãæ¨æ¸¬ãããããã«ã¯ãè¤åæã¯å¿
ãã{ return å¼ ; }ã®å½¢ã§ãªããã°ãªããªããã¤ã¾ããreturnæã²ã¨ã¤ã§ãªããã°ãªããªãã¨ãããã¨ã ãreturnæ以å¤ã«ãè¤æ°ã®æãããå ´åãæ»ãå¤ã®åã¯voidã§ããã
// ã¨ã©ã¼ãæ»ãå¤ã®åã¯voidã ããå¤ãè¿ãã¦ãã
[]
{
int x = 0 ;
return x ;
}() ;
// OKãæ»ãå¤ã®åããæ示çã«æå®ãã¦ããã
[] -> int
{
int x = 0 ;
return x ;
}() ;
ããã¤ãä¾ãæããã
// æ»ãå¤ã®åã¯int
auto type1 = []{ return 0 ; }() ;
// æ»ãå¤ã®åã¯double
auto type2 = []{ return 0.0 ; }() ;
// æ»ãå¤ã®åã¯void
[]{ }() ;
[]
{
int x = 0 ;
x = 1 ;
}() ;
ã©ã ãå¼ã®å¼æ°ã¯ãé常ã®é¢æ°ã¨åãããã«è¨è¿°ã§ããã
int main()
{
auto f = []( int a, float b ) { return a ; }
f( 123, 3.14f ) ;
}
è¤åæã¯ãé常ã®é¢æ°ã®æ¬ä½ã¨åãããã«æ±ãããã
int main()
{
// é常ã®é¢æ°ã¨åãããã«æãæ¸ãã
auto f =
[] {
int x = 0 ;
++x ;
};
f() ;
auto g = []
{ // ãã¡ãããè¤æ°ã®æãæ¸ãã
int x = 0 ;
++x ; ++x ; ++x ;
} ;
g() ;
}
ã¯ãã¼ã¸ã£ã¼ãªãã¸ã§ã¯ãã¯ãå¤æ°ã¨ãã¦ä¿æã§ããã
#include <functional>
int main()
{
// autoæå®åã使ãæ¹æ³
auto f = []{} ;
f() ;
// std::functionã使ãæ¹æ³
std::function< void (void) > g = []{} ;
g() ;
}
ã©ã ãå¼ã¯ããã³ãã¬ã¼ãå¼æ°ã«ã渡ããã
template < typename Func >
void f( Func func )
{
func() ; // é¢æ°ãªãã¸ã§ã¯ããå¼ã³åºã
}
int main()
{
f( []{ std::cout << "hello" << std::endl ; } ) ;
}
ã©ã ãå¼ã®ä½¿ãæ¹ã®ä¾ã示ããä¾ãã°ãstd::vectorã®å
¨è¦ç´ ããæ¨æºåºåã«åºåãããã¨ããã
#include <iostream>
#include <vector>
struct Print
{
void operator () ( int value ) const
{ std::cout << value << std::endl ; }
} ;
int main()
{
std::vector<int> v = { 1, 2, 3, 4, 5 } ;
std::for_each( v.begin(), v.end(), Print() ) ;
}
ãã®ä¾ã§ã¯ãæ¬è³ªçã«ã¯ãã£ãä¸è¡ã®ã³ã¼ããæ¸ãã®ã«ãããããé¢æ°ãªãã¸ã§ã¯ãããã©ããå¥ã®å ´æã«å®ç¾©ããªããã°ãªããªããã©ã ãå¼ã使ãã°ããã®å ´ã«æ¸ããã¨ãã§ããã
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> v = { 1, 2, 3, 4, 5 } ;
std::for_each( v.begin(), v.end(),
[](int value){ std::cout << value << std::endl ; } ) ;
}
é¢æ°å
ã«é¢æ°ãæ¸ããã¨ãã§ããã®ã¯ã確ãã«æ軽ã§ä¾¿å©ã ãããããã©ã ãå¼ã¯ãåã«ãã®å ´ã«é¢æ°ãæ¸ãã ãã§ã¯çµãããªããã©ã ãå¼ã¯ãé¢æ°ã®ãã¼ã«ã«å¤æ°ããã£ããã£ã¼ã§ããã
#include <iostream>
template < typename Func >
void call( Func func )
{
func() ; // helloã¨è¡¨ç¤ºãã
}
int main()
{
std::string str = "hello" ;
// mainé¢æ°ã®ãã¼ã«ã«å¤æ°strããã©ã ãå¼ã®ä¸ã§ä½¿ã
auto f = [=]{ std::cout << str << std::endl ; } ;
f() ;
// ãã¡ãããä»ã®é¢æ°ã«æ¸¡ããã
call( f ) ;
}
ãã®ããã«ãã©ã ãå¼ãå®ç¾©ããã¦ããé¢æ°ã®ãããã¯ã¹ã³ã¼ãã®ä¸ã®ãã¼ã«ã«å¤æ°ãã使ããã¨ãã§ããããã®æ©è½ããå¤æ°ã®ãã£ããã£ã¼ã¨ããã
ãã®ãã©ã ãå¼ã§ãå®ç¾©ããã¦ããå ´æã®ãã¼ã«ã«å¤æ°ã使ããã¨ããã®ã¯ãä¸è¦ãå¥å¦ã«æãããããããªãããããå®ã®ã¨ãããããã¯åãªãã·ã³ã¿ãã¯ã¹ã·ã¥ã¬ã¼ã«ãããªããåããã¨ã¯ãå¾æ¥ã®é¢æ°ãªãã¸ã§ã¯ãã§ãè¡ããã詳ããã¯å¾è¿°ããã
ãã¡ãããã¯ãã¼ã¸ã£ã¼ãªãã¸ã§ã¯ããã©ã®ããã«å®è£
ããããã¯ãå®è£
ã«ããç°ãªãããããåºæ¬çã«ãã©ã ãå¼ã¯ããã®ãããªé¢æ°ãªãã¸ã§ã¯ãã¸ã®ãã·ã³ã¿ãã¯ã¹ã·ã¥ã¬ã¼ã«éããªãã
[]ã®ä¸èº«ããã©ã ããã£ããã£ã¼ã¨ãããã©ã ããã£ããã£ã¼ã®ä¸ã«ã¯ããã£ããã£ã¼ãªã¹ããè¨è¿°ã§ãããå¤æ°ã®ãã£ããã£ã¼ãããã«ã¯ããã£ããã£ã¼ãªã¹ãã«ãã©ã®ããã«ãã£ããã£ã¼ãããããæå®ããªããã°ãªããªããå¤æ°ã®ãã£ããã£ã¼ã«ã¯ãäºç¨®é¡ãããã³ãã¼ã§ãã£ããã£ã¼ãããããªãã¡ã¬ã³ã¹ã§ãã£ããã£ã¼ãããã®éãã§ããã
int main()
{
int x = 0 ;
// ã³ãã¼ãã£ããã£ã¼
[=] { x ; }
// ãªãã¡ã¬ã³ã¹ãã£ããã£ã¼
[&] { x ; }
}
ãã£ããã£ã¼ãªã¹ãã«=ãè¨è¿°ããã¨ãã³ãã¼ãã£ããã£ã¼ã«ãªãã&ãè¨è¿°ããã¨ããªãã¡ã¬ã³ã¹ãã£ããã£ã¼ã«ãªãã
ã³ãã¼ãã£ããã£ã¼ã®å ´åãå¤æ°ã¯ã¯ãã¼ã¸ã£ã¼ãªãã¸ã§ã¯ãã®ãã¼ã¿ã¡ã³ãã¼ã¨ãã¦ãã³ãã¼ãããããªãã¡ã¬ã³ã¹ãã£ããã£ã¼ã®å ´åã¯ãã¯ãã¼ã¸ã£ã¼ãªãã¸ã§ã¯ãã«ãå¤æ°ã¸ã®åç
§ãä¿æãããã
ã³ãã¼ãã£ããã£ã¼ã®å ´åã¯ãã©ã ãå¼ããããã®å¤æ°ãæ¸ãæãããã¨ãã§ããªãã
int main()
{
int x = 0 ;
[=]
{ // ã³ãã¼ãã£ããã£ã¼
int y = x ; // OKãèªããã¨ã¯ã§ãã
x = 0 ; // ã¨ã©ã¼ãæ¸ãæãããã¨ã¯ã§ããªã
} ;
[&]
{ // ãªãã¡ã¬ã³ã¹ãã£ããã£ã¼
int y = x ; // OK
x = 0 ; // OK
} ;
}
ããã¯ãã¯ãã¼ã¸ã£ã¼ãªãã¸ã§ã¯ãã®operator()ããconstæå®ããã¦ããããã§ãããã©ã ãå¼ã«mutableãæå®ããã¦ããå ´åãoperator()ã¯ãconstæå®ãããªãã®ã§ãæ¸ãæãããã¨ãã§ããã
int main()
{
int x = 0 ;
[=]() mutable
{
int y = x ; // OK
x = 0 ; // OK
} ;
}
ãªãã¡ã¬ã³ã¹ãã£ããã£ã¼ã®å ´åã¯ãå¤æ°ã®å¯¿å½ã«æ°ãã¤ããªããã°ãªããªãã
#include <functional>
int main()
{
std::function< void ( void ) > f ;
std::function< void ( void ) > g ;
{
int x = 0 ;
f = [&]{ x ; } ; // ãªãã¡ã¬ã³ã¹ãã£ããã£ã¼
g = [=]{ x ; } ; // ã³ãã¼ãã£ããã£ã¼
}
f() ; // ã¨ã©ã¼ãxã®å¯¿å½ã¯ããã§ã«å°½ãã¦ããã
g() ; // OK
}
ãã¼ã«ã«å¤æ°ã®å¯¿å½ã¯ããã®ãããã¯ã¹ã³ã¼ãå
ã§ããããã®ä¾ã§ãfãå¼ã³åºãã¨ãã«ã¯ããã§ã«ãxã®å¯¿å½ã¯å°½ãã¦ããã®ã§ãã¨ã©ã¼ã«ãªãã
ã©ã ãå¼ããã£ããã£ã¼ã§ããã®ã¯ãã©ã ãå¼ãè¨è¿°ããã¦ããé¢æ°ã®ãæãå¤å´ã®ãããã¯ã¹ã³ã¼ãå
ã§ããã
int main()
{ // é¢æ°ã®æãå¤å´ã®ãããã¯ã¹ã³ã¼ã
int x ;
{
int y ;
// xãyããã£ããã£ã¼ã§ããã
[=]{ x ; y ; } ;
}
}
é¢æ°ã®æãå¤å´ã®ãããã¯ã¹ã³ã¼ã以å¤ã®ã¹ã³ã¼ããä¾ãã°ã°ãã¼ãã«å¤æ°ãªã©ã¯ããã£ããã£ã¼ããã«ã¢ã¯ã»ã¹åºæ¥ãã
// ã°ãã¼ãã«ã¹ã³ã¼ãã®å¤æ°
int x = 0 ;
int main()
{
// ãã£ããã£ã¼ããå¿
è¦ã¯ãªã
[]{ x ; } ;
}
å¤æ°ãã¨ã«ããã£ããã£ã¼æ¹æ³ãæå®ã§ããã
int main()
{
int a = 0 ;
int b = 0 ;
[ a, &b ]{} ;
}
å¤æ°ã®ãã£ããã£ã¼æ¹æ³ããããããæå®ããå ´åããã£ããã£ã¼ãªã¹ãã®ä¸ã«ãå¤æ°åãè¨è¿°ããããã®æãåã«å¤æ°åã ããè¨è¿°ããå ´åãã³ãã¼ãã£ããã£ã¼ã«ãªããå¤æ°åã®åã«&ãã¤ããå ´åããªãã¡ã¬ã³ã¹ãã£ããã£ã¼ã«ãªãã
ãã£ããã£ã¼ãããå¤æ°ãããããããå ´åããã¡ãã¡ååããã¹ã¦è¨è¿°ããã®ã¯é¢åã§ããã®ã§ãããã©ã«ãã®ãã£ããã£ã¼æ¹æ³ãæå®ã§ããããããããã©ã«ããã£ããã£ã¼ï¼default captureï¼ã¨ããããã®æãããã©ã«ããã£ããã£ã¼ã«ç¶ãã¦ãåã
ã®å¤æ°åã®ãã£ããã£ã¼æ¹æ³ãæå®ã§ããã
int main()
{
int a = 0 ; int b = 0 ; int c = 0 ; int d = 0 ;
// ããã©ã«ãã¯ã³ãã¼ãã£ããã£ã¼
[=]{ a ; b ; c ; d ; } ;
// ããã©ã«ãã¯ãªãã¡ã¬ã³ã¹ãã£ããã£ã¼
[&]{ a ; b ; c ; d ; } ;
// aã®ã¿ãªãã¡ã¬ã³ã¹ãã£ããã£ã¼
[=, &a]{} ;
// aã®ã¿ã³ãã¼ãã£ããã£ã¼
[&, a]{} ;
// a, bã®ã¿ãªãã¡ã¬ã³ã¹ãã£ããã£ã¼
[=, &a, &b]{} ;
// ããã©ã«ããã£ããã£ã¼ã使ããªã
[a]{} ;
}
ãã®ã¨ããããã©ã«ããã£ããã£ã¼ã¨åããã£ããã£ã¼æ¹æ³ããåã
ã®ãã£ããã£ã¼ã§æå®ãããã¨ã¯ã§ããªãã
int main()
{
int a = 0 ; int b = 0 ;
// ã¨ã©ã¼ãããã©ã«ããã£ããã£ã¼ã¨åã
[=, a]{} ;
// OK
[=, &a]{} ;
// ã¨ã©ã¼ãããã©ã«ããã£ããã£ã¼ã¨åã
[&, &a]{} ;
// OK
[&, a]{} ;
}
ãã£ããã£ã¼ãªã¹ãå
ã§ãåãååãè¤æ°æ¸ããã¨ã¯ã§ããªãã
int main()
{
int x = 0 ;
// ã¨ã©ã¼
[x, x]{} ;
}
ãã¨ãããã£ããã£ã¼æ¹æ³ãåãã§ãã£ãã¨ãã¦ããã¨ã©ã¼ã«ãªãã
ããã©ã«ããã£ããã£ã¼ãæå®ããã¦ããã©ã ãå¼ã®é¢æ°ã®æ¬ä½ã§ããã£ããã£ã¼ã§ããå¤æ°ã使ã£ãå ´åããã®å¤æ°ã¯ãæé»çã«ãã£ããã£ã¼ãããã
å¤æ°ã®ãã£ããã£ã¼ã®å
·ä½çãªä½¿ç¨ä¾ã示ããä»ãvectorã®åè¦ç´ ã®åè¨ãæ±ããããã°ã©ã ãæ¸ãã¨ãããé¢æ°ãªãã¸ã§ã¯ãã§å®è£
ãããã¨ã以ä¸ã®ããã«ãªãã
struct Sum
{
int sum ;
Sum() : sum(0) { }
void operator ()( int value ) { sum += value ; }
} ;
int main()
{
std::vector<int> v = {1,2,3,4,5} ;
Sum sum = std::for_each( v.begin(), v.end(), Sum() ) ;
std::cout << sum.sum << std::endl ;
}
ããã¯ãæããã«åããã«ãããsum += valueã¨ããçãã³ã¼ãã®ããã«ãé¢æ°ãªãã¸ã§ã¯ããå®ç¾©ããªããã°ãªããªããããã®åæ±ãé¢åã§ããããã®ãããå¤ãã®ããã°ã©ãã¯ãSTLã®ã¢ã«ã´ãªãºã ã使ããããèªåã®ã«ã¼ããæ¸ããããã
int main()
{
std::vector<int> v = {1,2,3,4,5} ;
int sum = 0 ;
for ( auto iter = v.begin() ; iter != v.end() ; ++iter )
{
sum += *iter ;
}
std::cout << sum << std::endl ;
}
ããããã«ã¼ããææ¸ãããã®ã¯åããã«ããããééãã®å
ã§ãããã©ã ãå¼ã®ãã£ããã£ã¼ã¯ããã®åé¡ã解決ãã¦ãããã
int main()
{
std::vector<int> v = {1,2,3,4,5} ;
int sum = 0 ;
std::for_each( v.begin(), v.end(),
[&]( int value ){ sum += value ; }
) ;
std::cout << sum << std::endl ;
}
ããã§ãã³ã¼ãã¯åããããããªããã¾ããã«ã¼ããææ¸ãããªãã®ã§ãééããæ¸ãã
ã©ã ãå¼ãè©ä¾¡ãããçµæã¯ãã¯ãã¼ã¸ã£ã¼ãªãã¸ã§ã¯ãï¼closure objectï¼ã«ãªããããã¯ãä¸ç¨®ã®é¢æ°ãªãã¸ã§ã¯ãã§ããã®åã¯ãã¦ãã¼ã¯ã§ç¡åãªå®è£
ä¾åã®ã¯ã©ã¹ã§ããã¨ããã¦ããããã®åã¯ãé常ã«éå®çã«ãã使ããªããä¾ãã°ãã©ã ãå¼ã¯ãæªè©ä¾¡å¼ã®ä¸ã§ä½¿ããã¨ãåºæ¥ãªããããã¯ãdecltypeãsizeofã®ä¸ã§ä½¿ããã¨ãåºæ¥ãªãã¨ãããã¨ãæå³ããã
using type = decltype([]{}) ; // ã¨ã©ã¼
sizeof([]{}) ; // ã¨ã©ã¼
// OK
auto f = []{} ;
ã¯ãã¼ã¸ã£ã¼ãªãã¸ã§ã¯ããã©ã®ããã«å®è£
ããããã¯ãå®è£
ä¾åã§ãããããããä»ã説æã®ããã«ãå®è£
ã®ä¸ä¾ã示ãã
int main()
{
int a = 0 ; int b = 0 ;
auto f = [a, &b](){ a ; b ; } ;
f() ;
}
ä¾ãã°ããã®ãããªã³ã¼ãããã£ãã¨ããã¨ãä¾ãã°ã以ä¸ã®ããã«å®è£
ã§ããã
class Closure // æ¬æ¥ãã¦ã¼ã¶ã¼å´ãã使ããååã¯åå¨ããªã
{
private :
// aã¯ã³ãã¼ãã£ããã£ã¼ãbã¯ãªãã¡ã¬ã³ã¹ãã£ããã£ã¼
int a ; int & b ;
public :
Closure(int & a, int & b )
: a(a), b(b) { }
// ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ãæé»çã«å®ç¾©ããã
Closure( Closure const & ) = default ;
// ã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ãæé»çã«å®ç¾©ãããå¯è½æ§ããã
Closure( Closure && ) = default ;
// ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯deleteå®ç¾©ããã
Closure() = delete ;
// ã³ãã¼ä»£å
¥æ¼ç®åã¯deleteå®ç¾©ããã
Closure & operator = ( Closure const & ) = delete ;
inline void operator () ( void ) const
{ a ; b ; }
} ;
int main()
{
int a = 0 ; int b = 0 ;
auto f = Closure(a, b) ;
f() ;
}
ã¯ãã¼ã¸ã£ã¼ãªãã¸ã§ã¯ãã¯ãã¡ã³ãã¼é¢æ°ã¨ãã¦ãoperator ()ãæã¤ãããã«ãããé¢æ°å¼ã³åºãã®æ¼ç®åã§ãé¢æ°ã®ããã«å¼ã³åºããã¨ãã§ããããã£ããã£ã¼ããå¤æ°ã¯ããã¼ã¿ã¡ã³ãã¼ã¨ãã¦æã¤ããã®operator ()ã¯ãinlineã§ãããã¾ããmutableæå®ããã¦ããªãå ´åãconstæå®ããã¦ãããããã«ãããã³ãã¼ãã£ããã£ã¼ããå¤æ°ã¯ãæ¸ãæãããã¨ãã§ããªããmutableãæå®ããã¦ããå ´åãconstã§ã¯ãªããªãã®ã§ãæ¸ãæãããã¨ãã§ããã
int main()
{
int x = 0 ;
// ã¨ã©ã¼
[x]() { x = 0 ; } ;
// OK
[x]() mutable { x = 0 ; } ;
}
ã©ã ãå¼ã®ä»®å¼æ°ãªã¹ãã«ã¯ãããã©ã«ãå¼æ°ãæå®ã§ããªãã
// ã¨ã©ã¼
[](int x = 0){} ;
ã©ã ãå¼ã¯ãä¾å¤æå®ã§ããã
[]() noexcept {} ;
ã©ã ãå¼ã«ä¾å¤æå®ãããã¨ãã¯ãã¼ã¸ã£ã¼ãªãã¸ã§ã¯ãã®operator ()ã«ãåãä¾å¤æå®ããªããããã®ã¨è§£éãããã
ã¯ãã¼ã¸ã£ã¼ãªãã¸ã§ã¯ãã«ã¯ãã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ãæé»çã«å®ç¾©ããããã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ãå¯è½ãªå ´åãæé»çã«å®ç¾©ããããããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¨ãã³ãã¼ä»£å
¥æ¼ç®åã¯ãdeleteå®ç¾©ããããããã¯ã¤ã¾ããåæåã¯ã§ããããã³ãã¼ä»£å
¥ã¯ã§ããªãã¨ãããã¨ãæå³ããã
// åæåã¯ã§ããã
auto f = []{} ;
// OK fã¯ã©ã ãå¼ã§ã¯ãªãã®ã§å¯è½
using closure_type decltype(f) ;
// OK åæåã¯ã§ãã
closure_type g = f ;
// ã¨ã©ã¼ãããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯åå¨ããªã
closure_type h ;
// ã¨ã©ã¼ãã³ãã¼ä»£å
¥æ¼ç®åã¯åå¨ããªãã
h = f ;
é¢æ°ãã¤ã³ã¿ã¼ã¸ã®å¤æ
ã©ã ããã£ããã£ã¼ã使ããªãã©ã ãå¼ã®ã¯ãã¼ã¸ã£ã¼ãªãã¸ã§ã¯ãã¯ãåä¸ã®å¼æ°ã¨æ»ãå¤ã®é¢æ°ãã¤ã³ã¿ã¼ã¸ã®å¤æé¢æ°ãæã¤ã
void (*ptr1)(void) = []{} ;
auto (*ptr2)(int, int, int) -> int = [](int a, int b, int c) -> int { return a + b + c ; };
// å¼ã³åºãã
ptr1() ; ptr2(1, 2, 3) ;
ã©ã ããã£ããã£ã¼ã使ã£ã¦ããã¯ãã¼ã¸ã£ã¼ãªãã¸ã§ã¯ãã¯ãé¢æ°ãã¤ã³ã¿ã¼ã«å¤æã§ããªãã
int main()
{
int x = 0 ;
// ã¨ã©ã¼ãå¤æã§ããªã
auto (*ptr1)(void) -> int = [=] -> int{ return x ; } ;
auto (*ptr2)(void) -> int = [&] -> int{ return x ; } ;
}
å¤æ°ããã£ããã£ã¼ããªãã©ã ãå¼ã¨ããã®ã¯ãé¢æ°ãªãã¸ã§ã¯ãã§ã¯ãªããåãªãé¢æ°ã«ç½®ãæãããã¨ãã§ããã®ã§ããã®ãããªæ©è½ãæä¾ããã¦ããããã®æ©è½ã¯ãã¾ã ãã³ãã¬ã¼ãã使ã£ã¦ããªãæ¢åã®ã³ã¼ããã©ã¤ãã©ãªã¨ã®ç¸äºå©ç¨ã®ããã«ç¨æããã¦ããã
ã©ã ãå¼ã®ãã¹ã
ã©ã ãå¼ã¯ãã¹ãã§ããã
[]{ // å¤å´ã®ã©ã ãå¼
[]{} ; // å
å´ã®ã©ã ãå¼
} ;
ãã®æãåé¡ã«ãªãã®ã¯ãå¤æ°ã®ãã£ããã£ã¼ã ãå
å´ã®ã©ã ãå¼ã¯ãå¤å´ã®ã©ã ãå¼ã®ãããã¯ã¹ã³ã¼ãããè¦ããå¤æ°ããããã£ããã£ã¼ãããã¨ã¯ã§ããªãã
int main()
{
int a = 0 ; int b = 0 ;
[b]{ // å¤å´ã®ã©ã ãå¼
int c = 0 ;
[=]{ // å
å´ã®ã©ã ãå¼
a ; // ã¨ã©ã¼ãaã¯ãã£ããã£ã¼ã§ããªãã
b ; // OK
c ; // OK
} ;
} ;
}
å¤å´ã®ã©ã ãå¼ããããã©ã«ããã£ããã£ã¼ã«ãã£ã¦ãæé»çã«å¤æ°ããã£ããã£ã¼ãã¦ããå ´åã¯ãå
å´ã®ã©ã ããããã®å¤æ°ããã£ããã£ã¼ã§ããã
int main()
{
int a = 0 ;
[=]{ // å¤å´ã®ã©ã ãå¼
[=]{ // å
å´ã®ã©ã ãå¼
a ; // OK
} ;
} ;
}
åºæ¬çã«ã©ã ãå¼ã¯ããã®ã©ã ãå¼ã使ããã¦ãããããã¯ã¹ã³ã¼ãã®ãã¼ã«ã«å¤æ°ãããã£ããã£ã¼ã§ããªããããããå®ã¯ããã¼ã¿ã¡ã³ãã¼ã使ããã¨ãã§ããã
struct C
{
int x ;
void f()
{
[=]{ x ; } ; // OKããã ããããã¯ãã£ããã£ã¼ã§ã¯ãªããã¨ã«æ³¨æ
}
} ;
ãã®ããã«ãéstaticãªã¡ã³ãã¼é¢æ°ã®ã©ã ãå¼ã§ã¯ããã¼ã¿ã¡ã³ãã¼ã使ããã¨ãã§ãããããããããã¯ããã¼ã¿ã¡ã³ãã¼ããã£ããã£ã¼ãã¦ããããã§ã¯ãªãããã®è¨¼æ ã«ããã¼ã¿ã¡ã³ãã¼ãç´æ¥ãã£ããã£ã¼ãããã¨ããã¨ãã¨ã©ã¼ã«ãªãã
struct C
{
int x ;
void f()
{
[x]{} ; // ã¨ã©ã¼ããã¼ã¿ã¡ã³ãã¼ã¯ãã£ããã£ã¼ã§ããªã
}
} ;
ã§ã¯ãã©ããã¦ãã¼ã¿ã¡ã³ãã¼ã使ããã®ããä¸ä½ä½ããã£ããã£ã¼ãã¦ããã®ããå®ã¯ãããã¯thisããã£ããã£ã¼ãã¦ããã®ã§ãããã©ã ãå¼ã¯ãthisããã£ããã£ã¼ã§ããã
struct C
{
int x ;
void f()
{
[this]{ this->x ; } ;
}
} ;
ã©ã ãå¼ã®é¢æ°ã®æ¬ä½ã§ã¯ãthisã¯ãã¯ãã¼ã¸ã£ã¼ãªãã¸ã§ã¯ãã¸ã®ãã¤ã³ã¿ã¼ã§ã¯ãªããã©ã ãå¼ã使ããã¦ããéstaticãªã¡ã³ãã¼é¢æ°ã®thisããã£ããã£ã¼ãããã®ã¨è§£éããããthisã¯ãå¿
ãã³ãã¼ãã£ããã£ã¼ããããã¨ããã®ããããããthisã¯ãã¤ã³ã¿ã¼ãªã®ã§ããªãã¡ã¬ã³ã¹ãã£ããã£ã¼ãã¦ãããã¾ãæå³ã¯ãªãã
struct C
{
int x ;
void f()
{
[this]{} ; // OK
[&this]{} ; // ã¨ã©ã¼ãthisã¯ãªãã¡ã¬ã³ã¹ãã£ããã£ã¼ã§ããªã
}
} ;
ã©ã ãå¼ã«ããã©ã«ããã£ããã£ã¼ãæå®ããã¦ãã¦ããã¼ã¿ã¡ã³ãã¼ã使ããã¦ããå ´åãthisã¯æé»çã«ãã£ããã£ã¼ããããããã©ã«ããã£ããã£ã¼ãã³ãã¼ã§ããªãã¡ã¬ã³ã¹ã§ããthisã¯å¿
ãã³ãã¼ãã£ããã£ã¼ãããã
struct C
{
int x ;
void f()
{
[=]{ x ; } ; // thisãã³ãã¼ãã£ããã£ã¼ãã
[&]{ x ; } ; // thisãã³ãã¼ãã£ããã£ã¼ãã
}
} ;
thisã®ãã£ããã£ã¼ã¯ã注æãè¦ããããã§ã«è¿°ã¹ãããã«ããã¼ã¿ã¡ã³ãã¼ã¯ããã£ããã£ã¼ã§ããªããã©ã ãå¼ã§ãã¼ã¿ã¡ã³ãã¼ã使ãã¨ãããã¨ã¯ãthisããã£ããã£ã¼ããã¨ãããã¨ã§ããããã¼ã¿ã¡ã³ãã¼ã¯ãthisãéãã¦ä½¿ããããããã¯ããã¼ã¿ã¡ã³ãã¼ã¯åç
§ã§ä½¿ãããã¨ãããã¨ãæå³ãããã¨ãããã¨ã¯ããããã¯ãã¼ã¸ã£ã¼ãªãã¸ã§ã¯ãã®operator ()ãå¼ã°ããéã«ãthisãæã示ããªãã¸ã§ã¯ããç¡å¹ã«ãªã£ã¦ããå ´åãã¨ã©ã¼ã¨ãªã£ã¦ãã¾ãã
struct C
{
int x ;
std::function< int (void) > f()
{
return [this]{ return x ; } ;
}
} ;
int main()
{
std::function< int (void) > f ;
{
C c ;
f = c.f() ;
}// cã®å¯¿å½ã¯ãã§ã«çµãã£ã¦ãã
f() ; // ã¨ã©ã¼
}
ãã¼ã¿ã¡ã³ãã¼ãã³ãã¼ãã£ããã£ã¼ããæ¹æ³ã¯ãªãããããããä½åº¦ãè¿°ã¹ã¦ããããã«ããã¼ã¿ã¡ã³ãã¼ã¯ãã£ããã£ã¼ã§ããªããã§ã¯ãä¸ã®ä¾ã§ãã©ããã¦ããã¼ã¿ã¡ã³ãã¼ã®å¤ã使ãããå ´åã¯ã©ãããã°ããã®ãããã®å ´åãä¸åº¦ãã¼ã«ã«å¤æ°ã«ã³ãã¼ããã¨ããæ¹æ³ãããã
struct C
{
int x ;
std::function< int (void) > f()
{
int x = this->x ;
return [x]{ return x ; } ; // xã¯ãã¼ã«ã«å¤æ°ã®ã³ãã¼
}
} ;
ãã¡ãããåãååã«ããã®ãç´ãããããã°ãååãå¤ãã¦ãããã
ã©ã ãå¼ã§ãã¼ã¿ã¡ã³ãã¼ã使ãéã«ã¯ããã£ããã£ã¼ãã¦ããã®ã¯ãå®ã¯thisãªã®ã ã¨ãããã¨ã«æ³¨æããªããã°ãªããªãã
å¯å¤å¼æ°ãã³ãã¬ã¼ãã®é¢æ°ãã©ã¡ã¼ã¿ã¼ããã¯ãããã£ããã£ã¼ãªã¹ãã«æ¸ããã¨ãã§ããããã®å ´åãé常ã¨åãããã«ãããã¯å±éã«ãªãã
template < typename ... Types > void g( Types ... args ) ;
template < typename ... Types >
void f( Types ... args )
{
// æ示çãªãã£ããã£ã¼
[args...]{ g( args... ) ; } ;
[&args...]{ g( args... ) ; } ;
// æé»çãªãã£ããã£ã¼
[=]{ g( args... ) ; } ;
[&]{ g( args... ) ; } ;
}
å¾ç½®å¼ã¯ã主ã«ãªãã©ã³ãã®å¾ãã«æ¼ç®åãæ¸ããã¨ãããããå¼ã°ãã¦ãããå¾ç½®å¼ã®è©ä¾¡é åºã¯ãã¹ã¦ããå·¦ããå³ãã§ããã
å¼ [ å¼ ]
å¼ [ åæåãªã¹ã ]
operator []ã¯ãæ·»åã¨å¼ã°ããå¼ã§ãããããã¯ãé
åã®è¦ç´ ã«ã¢ã¯ã»ã¹ããããã«ç¨ãããããã©ã¡ããçæ¹ã®å¼ã¯ãTã¸ã®ãã¤ã³ã¿ã¼åã§ãªããã°ãªãããããçæ¹ã¯ãunscoped enumããæ´æ°åã§ãªããã°ãªããªããå¼ã®çµæã¯ãlvalueã®Tã¨ãªããå¼ãE1[E2] ã¯ã*((E1)+(E2)) ã¨æ¸ãã®ã«çããã
int x[3] ;
// *(x + 1)ã¨åã
x[1] ;
ãã®å ´åãxã«ã¯ãé
åãããã¤ã³ã¿ã¼ã¸ã®åå¤æãé©ç¨ããã¦ããã
ãã©ã¡ããçæ¹ã®å¼ãã¨ããã®ã¯ãæåéããã©ã¡ããçæ¹ã§ããããã¨ãã°ãx[1]ã¨ãã¹ãã¨ãããã1[x]ã¨ãã¦ããåãæå³ã«ãªãã
int x[3] ;
// ã©ã¡ããåãæå³ã
x[1] ;
1[x] ;
ãã£ã¨ããé常ã¯ãä¸ã¤ãã®å¼ããã¤ã³ã¿ã¼åã«ãã¦ãäºã¤ç®ã®å¼ãæ´æ°åã«ãããã¦ã¼ã¶ã¼å®ç¾©ã®operator []ã§ã¯ããã®ãããªãã¨ã¯ã§ããªãã
ã¦ã¼ã¶ã¼å®ç¾©ã®operator []ã®å ´åã[]ã®ä¸ã®å¼ã«ãåæåãªã¹ãã渡ããã¨ãã§ãããããã¯ãã©ã®ããã«ä½¿ã£ã¦ããããããä¾ãã°ä»¥ä¸ã®ããã«ä½¿ããã
struct C
{
int data[10][10][10] ;
int & operator []( std::initializer_list<std::size_t> list )
{
if ( list.size() != 3 ) { /* ã¨ã©ã¼å¦ç */ }
auto iter = list.begin() ;
std::size_t const i = *iter ; ++iter ;
std::size_t const j = *iter ; ++iter ;
std::size_t const k = *iter ;
return data[i][j][k] ;
}
} ;
int main()
{
C c ;
c[{1, 2, 3}] = 0 ;
}
åæåãªã¹ãã使ãã°ããªã¼ãã¼ãã¼ããããoperator []ã«ãè¤æ°ã®å¼æ°ã渡ããã¨ãã§ããã
é¢æ°å¼ã³åºãï¼function callï¼ã®ææ³ã¯ã以ä¸ã®éãã
å¼ ( å¼æ°ã®ãªã¹ã )
é¢æ°å¼ã³åºãã«ã¯ãé常ã®é¢æ°å¼ã³åºãã¨ãã¡ã³ãã¼é¢æ°å¼ã³åºããããã
é常ã®é¢æ°ãå¼ã³åºãå ´åãå¼ã«ã¯ãé¢æ°ã¸ã®lvalueããé¢æ°ã¸ã®ãã¤ã³ã¿ã¼ã使ããã
void f( void ) { }
void g( int ) { }
void h( int, int, int ) { }
int main()
{
// ãé¢æ°ã¸ã®lvalueãã¸ã®é¢æ°å¼ã³åºã
f( ) ;
g( 0 ) ;
h( 0, 0, 0 ) ;
// é¢æ°ã¸ã®åç
§
void (&ref)(void) = f ;
// ãé¢æ°ã¸ã®lvalueãã¸ã®é¢æ°å¼ã³åºã
ref() ;
// é¢æ°ãã¤ã³ã¿ã¼
void (*ptr)(void) = &f ;
// é¢æ°ãã¤ã³ã¿ã¼ã¸ã®é¢æ°å¼ã³åºã
ptr() ;
}
staticãªã¡ã³ãã¼é¢æ°ã¯ãé常ã®é¢æ°å¼ã³åºãã«ãªãã
struct C { static void f(void) {} } ;
int main()
{
void (*ptr)(void) = &C::f ;
ptr() ; // é常ã®é¢æ°å¼ã³åºã
}
ã¡ã³ãã¼é¢æ°ãå¼ã³åºãå ´åãå¼ã«ã¯ãé¢æ°ã®ã¡ã³ãã¼ã®ååããã¡ã³ãã¼é¢æ°ã¸ã®ãã¤ã³ã¿ã¼å¼ã使ããã
struct C
{
void f(void) {}
void g(void)
{
// ã¡ã³ãã¼é¢æ°ã®å¼ã³åºã
f() ;
this->f() ;
(*this).f() ;
// ã¡ã³ãã¼é¢æ°ã¸ã®ãã¤ã³ã¿ã¼
void (C::* ptr)(void) = &C::f ;
// é¢æ°å¼ã³åºã
(this->*ptr)() ;
}
} ;
é¢æ°å¼ã³åºãå¼ã®çµæã®åã¯ãå¼ã§å¼ã³åºããé¢æ°ã®æ»ãå¤ã®åã«ãªãã
void f() ;
int g() ;
// å¼ã®çµæã®åã¯void
f() ;
// å¼ã®çµæã®åã¯int
g() ;
é¢æ°å¼ã³åºãã®çµæã®åã¯ãæ»ãå¤ã®åã«ãªããããã¯typeidãsizeofãdecltypeã®ãªãã©ã³ãã®ä¸ã§ããåæ§ã§ããã
// é¢æ°fã®æ»ãå¤ã®åã¯int
// ããªãã¡ãfãé¢æ°å¼ã³åºãããçµæã®åã¯int
int f() { return 0 ; }
int main()
{
// sizeof(int)ã¨åã
sizeof( f() ) ;
// typeid(int)ã¨åã
typeid( f() ) ;
// intåã®å¤æ°xã®å®£è¨ã¨å®ç¾©ã
decltype( f() ) x ;
}
é¢æ°ãå¼ã°ããéãä»®å¼æ°ã¯å¯¾å¿ããå®å¼æ°ã§åæåããããéstaticã¡ã³ãã¼é¢æ°ã®å ´åãthisä»®å¼æ°ãã¡ã³ãã¼é¢æ°ãå¼ã³åºããéã®ãªãã¸ã§ã¯ãã¸ã®ãã¤ã³ã¿ã¼ã§åæåãããã
ä»®å¼æ°ã«å¯¾ãã¦ãå
·ä½çãªä¸æãªãã¸ã§ã¯ããçæããããã©ããã¯ãå®è£
ä¾åã§ããããã¨ãã°ãå®è£
ã¯æé©åã®ããã«ãä¸æãªãã¸ã§ã¯ãã®çæãçç¥ãããããããªãã
ä»®å¼æ°ãåç
§ã®å ´åãã®ããã¦ãå¼ã°ããé¢æ°ã®ä¸ã§ä»®å¼æ°ãå¤æ´ãã¦ããå®å¼æ°ã¯å¤æ´ãããªãããã ããåããã¤ã³ã¿ã¼ã®å ´åãåç
§ãéãã¦åç
§å
ã®ãªãã¸ã§ã¯ããå¤æ´ãããå¯è½æ§ãããã
void f( int x, int & ref, int * ptr )
{
x = 1 ; // å®å¼æ°ã¯å¤æ´ãããªã
ref = 1 ; // å®å¼æ°ãå¤æ´ããã
*ptr = 1 ; // å®å¼æ°ã¯ããã¤ã³ã¿ã¼ã®åç
§ãéãã¦å¤æ´ããã
ptr = nullptr ; // å®å¼æ°ã®ãã¤ã³ã¿ã¼ã¯å¤æ´ãããªã
}
int main()
{
int x = 0 ; // å®å¼æ°
int * ptr = &x ;
f( x, x, ptr ) ;
}
å®å¼æ°ã®å¼ããã©ã®ãããªé çªã§è©ä¾¡ããããã¯æ±ºãããã¦ããªãããã ããå¼ã³åºãããé¢æ°ã®æ¬ä½ã«å
¥ãéã«ã¯ãå¼ã¯ãã¹ã¦è©ä¾¡ããã¦ããã
#include <iostream>
int f1(){ std::cout << "f1" << std::endl ; return 0 ; }
int f2(){ std::cout << "f2" << std::endl ; return 0 ; }
int f3(){ std::cout << "f3" << std::endl ; return 0 ; }
void g( int, int, int ){ }
int main( )
{
g( f1(), f2(), f3() ) ; // f1, f2, f3é¢æ°å¼ã³åºãã®é çªã¯åãããªã
}
ãã®ä¾ã§ã¯ãé¢æ°f1, f2, f3ãã©ã®é çªã§å¼ã°ããã®ããåãããªãããããã£ã¦ãæ¨æºåºåã«ã©ã®ãããªé çªã§æååãåºåãããããåãããªãããã ããé¢æ°gã®æ¬ä½ã«å
¥ãéã«ã¯ãf1, f2, f3ã¯ããã¹ã¦å¼ã³åºããã¦ããã
é¢æ°ã¯ãèªåèªèº«ãå¼ã³åºããã¨ãã§ããããããå帰å¼ã³åºãã¨ããã
void f()
{
f() ; // èªåèªèº«ãå¼ã³åºããç¡éã«ã¼ã
}
ãã ããmainé¢æ°ã ãã¯ç¹å¥ã§ãå帰å¼ã³åºãããããã¨ãã§ããªãã
int main()
{
main() ; // ã¨ã©ã¼
}
åå ( å¼ãªã¹ã )
åå åæåãªã¹ã
é¢æ°å½¢å¼ã®æ示çåå¤æï¼Explicit type conversion (functional notation)ï¼ã¨ã¯ãé¢æ°å¼ã³åºãã®ãããªææ³ã«ãããä¸ç¨®ã®ãã£ã¹ãã§ããã
struct S
{
S( int ) { }
S( int, int ) { }
} ;
int main()
{
int() ;
int{} ;
S( 0 ) ;
S( 1, 2 ) ;
}
ååã¨ãã¦ä½¿ããã®ã¯ãåç´åæå®åããtypenameæå®åã§ãããåç´åæå®åã§ãªããã°ãªããªãã¨ãããã¨ã«ã¯ã注æããªããã°ãªããªãããã¨ãã°ããã¤ã³ã¿ã¼ããªãã¡ã¬ã³ã¹ãé
åãªã©ãç´æ¥æ¸ããã¨ã¯ã§ããªãããã ããtypedefåã¯ä½¿ããã
int x = 0 ;
// ãããã¯ã¨ã©ã¼
int *(&x) ;
int &(x) ;
// typedefåã¯ä½¿ãã
using type = int * ;
type(&x) ;
åç´åæå®åã®ä¸ã§ããautoã¨decltypeã¯ã注æãå¿
è¦ã§ãããã¾ããautoã¯ä½¿ããªãã
auto(0) ; // ã¨ã©ã¼
decltypeã¯ä½¿ããããã ããé常ã«ä½¿ãã¥ããã®ã§ã使ãã¹ãã§ã¯ãªãã
// intåãintåã«ãã£ã¹ã
// int(0) ã¨åã
decltype(0)(0) ;
ãã¨ãã°ã以ä¸ã®ã³ã¼ãã¯ã¨ã©ã¼ã§ããã
int x ;
decltype(x)(x) ; // ã¨ã©ã¼
ããã¯ãææ³ãææ§ã ããã ã詳ããã¯ãææ§è§£æ±ºãåç
§ãä½ãèµ·ãã£ã¦ãããã¨ããã¨ãdecltype(x)(x)ã¯ããã£ã¹ãã§ã¯ãªããå¤æ°ã®å®£è¨ã ã¨ã¿ãªããã¦ãããdecltype(x)ã¯ãintã¨ããåã§ããã
// decltype(x)(x) ã¨åã
// decltype(x)(x) â int (x) â int x
int x ;
ãã®ãããdecltypeãé¢æ°å½¢å¼ã®ãã£ã¹ãã§ä½¿ãã®ã¯ãåé¡ãå¤ãã使ããªãã°ãtypedefåãã¤ãã¦ãã使ãããstatic_castã使ãã¹ãã§ããã
int x ;
using type = decltype(x) ;
type(x) ;
static_cast< decltype(x) >(x) ;
typenameæå®åã使ããã¨ãã§ããã
template < typename T >
void f()
{
typename T::type() ; // OK
}
å¼ãªã¹ããããã£ãã²ã¨ã¤ã®å¼ã§ããå ´åããã£ã¹ãã¨åãæå³ã«ãªãã
// intåããshortåã¸ã®ãã£ã¹ã
short(0) ;
// intåããdoubleåã¸ã®ãã£ã¹ã
double(0) ;
struct C { C(int) {} } ;
// å¤æé¢æ°ã«ãããintåããCåã¸ã®ãã£ã¹ã
C(0) ;
ååãã¯ã©ã¹åã§ããå ´åãT(x1, x2, x3)ã¨ããå½¢ã®å¼ã¯ãT t(x1, x2, x3)ã¨ããå½¢ã¨åãæå³ãæã¤ä¸æãªãã¸ã§ã¯ããçæãããã®ä¸æãªãã¸ã§ã¯ãããprvalueã®çµæã¨ãã¦è¿ããååãã¯ã©ã¹åã§ããå¼ãªã¹ããã²ã¨ã¤ãããªãå ´åã¯ããã£ã¹ãã§ããããã£ã¨ãããã®å ´åããã¦ã¼ã¶ã¼å®ç¾©ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ããå¤æé¢æ°ã¨ãã¦å¼ã³åºããããã¨ã«ãªãã®ã§ãæå³ã¯ãã¾ãå¤ãããªãã
struct C
{
C(int) {}
C(int, int) {}
C(int, int, int) {}
} ;
int main()
{
C(0) ; // ããã¯ãã£ã¹ããæå³ã¨ãã¦ã¯ããã¾ãéãã¯ãªã
C(1, 2) ;
C(1, 2, 3) ;
}
å¼ãªã¹ãã空ã®å ´åãã¤ã¾ããT()ã¨ããå½¢ã®å¼ã®å ´åãã¾ããTã¯é
ååã§ãã£ã¦ã¯ãªããªããTã¯å®å
¨ãªåããvoidã§ãªããã°ãªããªããå¼ã®çµæã¯ãå¤åæåãããåã®prvalueã®å¤ã«ãªããå¤åæåã«ã¤ãã¦ã¯ãåæååãåç
§ã
int() ; // intåã®0ã§åæåãããå¤
double() ; // doubleåã®0ã§åæåãããå¤
struct C {} ;
C() ; // ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãå¼ã°ããCã®å¤
voidåã®å ´åãå¤åæåã¯ãããªããå¼ã®çµæã®åã¯voidã§ããã
void() ; // çµæã¯void
æ¬å¼§ã§å²ã¾ããå¼ãªã¹ãã§ã¯ãªããåæåãªã¹ãã®å ´åãå¼ã®çµæã¯ãæå®ãããåã®ãåæåãªã¹ãã«ãã£ã¦ç´æ¥ãªã¹ãåæåãããprvalueã®ä¸æãªãã¸ã§ã¯ãã«ãªãã
#include <initializer_list>
struct C
{
C( std::initializer_list<int> ) { }
} ;
int main()
{
C{1,2,3} ;
}
çä¼¼ãã¹ãã©ã¯ã¿ã¼å¼ã³åºãã¨ã¯ããã¹ãã©ã¯ã¿ã¼ãæ示çã«å¼ã³åºããã¨ãã§ããä¸é£ã®å¼ã§ããã使ãæ¹ã¯ãoperator .ãoperator ->ã«ç¶ãã¦ãçä¼¼ãã¹ãã©ã¯ã¿ã¼åãæ¸ããããã«é¢æ°å¼ã³åºãã®operator ()ãæ¸ãããã®ä¸é£ã®å¼ããçä¼¼ãã¹ãã©ã¯ã¿ã¼å¼ã³åºãã¨ããããã®ãããªçä¼¼ãã¹ãã©ã¯ã¿ã¼åã«ç¶ãã¦ã¯ãé¢æ°å¼ã³åºãå¼ããé©ç¨ãããã¨ãã§ããªããå¼ã®çµæã¯voidã«ãªãã
// ãã®ã³ã¼ãã¯ãçä¼¼ãã¹ãã©ã¯ã¿ã¼å¼ã³åºãã®ææ³ã示ãããã ãã®ä¾ã§ãã
struct C {} ;
int main()
{
C c ;
c.~C() ; // çä¼¼ãã¹ãã©ã¯ã¿ã¼å¼ã³åºã
C * ptr = &c
ptr->~C() ; // çä¼¼ãã¹ãã©ã¯ã¿ã¼å¼ã³åºã
}
注æãã¹ããã¨ã¯ããã¹ãã©ã¯ã¿ã¼ãæ示çã«å¼ã³åºããã¨ãã¦ããæé»çã«å¼ã³åºããããã¹ãã©ã¯ã¿ã¼ã¯ãä¾ç¶ã¨ãã¦å¼ã³åºãããã¨ãããã¨ã§ããã
#include <iostream>
struct C
{
~C() { std::cout << "destructed." << std::endl ; }
} ;
int main()
{
{
C c ;
c.~C() ; // ãã¹ãã©ã¯ã¿ã¼ãå¼ã³åºã
}// ãããã¯ã¹ã³ã¼ãã®çµãã§ãããã¹ãã©ã¯ã¿ã¼ã¯æé»çã«å¼ã°ãã
C * ptr = new C ;
ptr->~C() ; // ãã¹ãã©ã¯ã¿ã¼ãå¼ã³åºã
delete ptr ; // ãã¹ãã©ã¯ã¿ã¼ãæé»çã«å¼ã°ããã
}
ãã®ããã«ãé常ã¯ããã¹ãã©ã¯ã¿ã¼ã®å¼ã³åºããéè¤ãã¦ãã¾ããäºéã«ãã¹ãã©ã¯ã¿ã¼ãå¼ã³åºãã®ã¯ã大æµã®å ´åãããã°ã©ã ä¸ã®ã¨ã©ã¼ã§ãããã§ã¯ãçä¼¼ãã¹ãã©ã¯ã¿ã¼å¼ã³åºãã¯ä½ã®ããã«ããã®ããå
·ä½çãªç¨éã¨ãã¦ã¯ãplacement newã¨çµã¿åããã¦ä½¿ãã¨ãããã¨ãããã
struct C { } ;
int main()
{
// placement newç¨ã®ã¹ãã¬ã¼ã¸ã確ä¿
void * storage = operator new( sizeof(C) ) ;
// placement new
C * ptr = new(storage) C ;
// ãã¹ãã©ã¯ã¿ã¼ãå¼ã³åºã
ptr->~C() ;
// placement newç¨ã®ã¹ãã¬ã¼ã¸ã解æ¾
operator delete( storage ) ;
}
ãã®çä¼¼ãã¹ãã©ã¯ã¿ã¼ã«ã¯ãdecltypeã使ããã¨ãã§ããã
struct C {} ;
int main()
{
C c ;
c.~decltype(c) ;
C * ptr = &c
ptr->~decltype(c) ;
}
ãã³ãã¬ã¼ãå¼æ°ã®å ´åãåãã¹ã«ã©ã¼åã§ãã£ã¦ããçä¼¼ãã¹ãã©ã¯ã¿ã¼å¼ã³åºããã§ããã
template < typename T >
void f()
{
T t ;
t.~T() ;
}
int main()
{
f<int>() ;
}
ããã«ãããã¸ã§ããªãã¯ãªãã³ãã¬ã¼ãã³ã¼ããæ¸ãããããªãã
ã¯ã©ã¹ã®ãªãã¸ã§ã¯ã . ã¡ã³ãã¼å
ã¯ã©ã¹ã®ãã¤ã³ã¿ã¼ -> ã¡ã³ãã¼å
ã¯ã©ã¹ã¡ã³ãã¼ã¢ã¯ã»ã¹ã¯ãååã®éããã¯ã©ã¹ã®ãªãã¸ã§ã¯ãããã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã¸ã®ãã¤ã³ã¿ã¼ã®ã¡ã³ãã¼ã«ã¢ã¯ã»ã¹ããããã®æ¼ç®åã§ããã
. æ¼ç®åã®å·¦å´ã®å¼ã¯ãã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã§ãªããã°ãªããªãã-> æ¼ç®åã®å·¦å´ã®å¼ã¯ãã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã¸ã®ãã¤ã³ã¿ã¼ã§ãªããã°ãªããªããæ¼ç®åã®å³å´ã¯ããã®ã¯ã©ã¹ããåºæ¬ã¯ã©ã¹ã®ã¡ã³ãã¼åã§ãªããã°ãªããªãã-> æ¼ç®åã使ã£ãå¼ãE1->E2ã¯ã(*(E1)).E2ã¨ããå¼ã¨ããªãã«ãªãã
struct Object
{
int x ;
static int y ;
void f() {}
} ;
int Object::y ;
int main()
{
Object obj ;
// . æ¼ç®å
obj.x = 0 ;
obj.y = 0 ;
obj.f() ;
Object * ptr = &obj ;
// -> æ¼ç®å
ptr->x = 0 ;
ptr->y = 0 ;
ptr->f() ;
}
ãããã¯ã©ã¹ã®ãªãã¸ã§ã¯ããã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã¸ã®ãã¤ã³ã¿ã¼ã表ãå¼ãä¾åå¼ã§ãããã¡ã³ãã¼åãã¡ã³ãã¼ãã³ãã¬ã¼ãã§ããããã³ãã¬ã¼ãå¼æ°ãæ示çã«æå®ãããå ´åãã¡ã³ãã¼åã®åã«ãtemplateãã¼ã¯ã¼ãã使ããªããã°ãªããªãã
struct Object
{
template < typename T >
void f() {}
} ;
template < typename T >
void f()
{
T obj ;
obj.f<int>() ; // ã¨ã©ã¼
obj.template f<int>() ; // OK
}
int main()
{
f<Object>() ;
}
ããã¯ã<æ¼ç®åãã>æ¼ç®åã¨ãææ³ãææ§ã«ãªãããã§ããããã®åé¡ã«ã¤ãã¦ã¯ããã³ãã¬ã¼ãç¹æ®åã®ååã§ãã解説ãã¦ããã
æ´¾çã«ãã£ã¦ãã¯ã©ã¹ã®ã¡ã³ãã¼åãææ§ãªå ´åãã¨ã©ã¼ã«ãªãã
struct Base1 { int x ; } ;
struct Base2 { int x ; } ;
struct Derived : Base1, Base2
{ } ;
int main()
{
Derived d ;
d.x ; // ã¨ã©ã¼
d.Base1::x ; // OK
d.Base2::x ; // OK
}
ããã§ã¯ãå¾ç½®å¼ã®ã¤ã³ã¯ãªã¡ã³ãã¨ãã¯ãªã¡ã³ãã«ã¤ãã¦è§£èª¬ãããåç½®å¼ã®ã¤ã³ã¯ãªã¡ã³ãã¨ãã¯ãªã¡ã³ãã«ã¤ãã¦ã¯ãåé
å¼ã®ã¤ã³ã¯ãªã¡ã³ãã¨ãã¯ãªã¡ã³ããåç
§ã
å¼ ++
å¼ --
å¾ç½®å¼ã®++æ¼ç®åã®å¼ã®çµæã¯ããªãã©ã³ãã®å¼ã®å¤ã«ãªãããªãã©ã³ãã¯ãå¤æ´å¯è½ãªlvalueã§ãªããã°ãªããªãããªãã©ã³ãã®åã¯ãæ°å¤åãããã¤ã³ã¿ã¼åã§ãªããã°ãªããªããå¼ãè©ä¾¡ãããã¨ããªãã©ã³ãã«1ãå ç®ããããã ããå¼ã®çµæã¯ããªãã©ã³ãã«1ãå ç®ããåã®å¤ã§ããã
int x = 0 ;
int result = x++ ;
// ããã§ãresult == 0, x == 1
å¼ã®çµæã®å¤ã¯ããªãã©ã³ãã®å¤ã¨å¤ããããªããããªãã©ã³ãã«ã¯ã1ãå ç®ãããã¨ãããã¨ã«æ³¨æããªããã°ãªããªãã
å¾ç½®å¼ã®--æ¼ç®åã¯ããªãã©ã³ããã1ãæ¸ç®ããããã以å¤ã¯ã++æ¼ç®åã¨å
¨ãåãããã«åãã
int x = 0 ;
int result = x-- ;
// ããã§ãresult == 0, x == -1
dynamic_cast < åå > ( å¼ )
dynamic_cast<T>(v)ã¨ããå¼ã¯ãvã¨ããå¼ãTã¨ããåã«å¤æããã便å®ä¸ãvãdynamic_castã®ãªãã©ã³ããTãdynamic_castã®å¤æå
ã®åã¨ãããå¤æå
ã®åã¯ã¯ã©ã¹ã¸ã®ãã¤ã³ã¿ã¼ããªãã¡ã¬ã³ã¹ããããã¯ãvoidã¸ã®ãã¤ã³ã¿ã¼åã§ãªããã°ãªããªãããªãã©ã³ãã¯ãå¤æå
ã®åãããã¤ã³ã¿ã¼ã®å ´åã¯ãã¤ã³ã¿ã¼ããªãã¡ã¬ã³ã¹ã®å ´åã¯ãªãã¡ã¬ã³ã¹ã§ãªããã°ãªããªãã
struct C {} ;
int main()
{
C c ;
// å¤æå
ã®åããã¤ã³ã¿ã¼ã®å ´åã¯ããªãã©ã³ãããã¤ã³ã¿ã¼
// å¤æå
ã®åããªãã¡ã¬ã³ã¹ã®å ´åã¯ããªãã©ã³ãããªãã¡ã¬ã³ã¹ã§ãªããã°ãªããªã
dynamic_cast<C &>(c) ; // OK
dynamic_cast<C *>(&c) ; // OK
// ãã¤ã³ã¿ã¼ããªãã¡ã¬ã³ã¹ãããä¸è´ãã¦ããªã
dynamic_cast<C *>(c) ; // ã¨ã©ã¼
dynamic_cast<C &>(&c) ; // ã¨ã©ã¼
}
ä»ãDerivedã¯ã©ã¹ããBaseã¯ã©ã¹ããæ´¾çããã¦ããã¨ããã
struct Base {} ;
struct Derived : Base {} ;
ãã®æãstatic_castã使ãã°ãBaseã¸ã®ãã¤ã³ã¿ã¼ããªãã¡ã¬ã³ã¹ãããDerivedã¸ã®ãã¤ã³ã¿ã¼ããªãã¡ã¬ã³ã¹ã«å¤æãããã¨ãã§ããã
int main()
{
Derived d ;
Base & base_ref = d ;
Derived & derived_ref = static_cast<Derived &>(base_ref) ;
Base * base_ptr = &d ;
Derived * derived_ptr = static_cast<Derived *>(base_ptr) ;
}
ãã®ä¾ã§ã¯ããã¤ã³ã¿ã¼ããªãã¡ã¬ã³ã¹ãæããæ¬å½ã®ãªãã¸ã§ã¯ãã¯ãDerivedã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã ã¨ãããã¨ãåãããã£ã¦ããã®ã§å®å
¨ã§ããããããããã¤ã³ã¿ã¼ããªãã¡ã¬ã³ã¹ã使ãå ´åã常ã«ãªãã¸ã§ã¯ãã®æ¬å½ã®ã¯ã©ã¹åãåããããã§ã¯ãªãã
void f( Base & base )
{
// baseãDerivedãåç
§ãã¦ãããã©ããã¯ãåãããªãã
Derived & d = static_cast<Derived &>(base) ;
}
int main()
{
Derived derived ;
f(derived) ; // ok
Base base ;
f(base) ; // ã¨ã©ã¼
}
ãã®ããã«ããã¤ã³ã¿ã¼ããªãã¡ã¬ã³ã¹ã®æã示ããªãã¸ã§ã¯ãã®æ¬å½ã®ã¯ã©ã¹åã¯ãå®è¡æã«ããåãããªãããããããªãã¸ã§ã¯ãã®åã«ãã£ã¦ãç¹å¥ãªå¦çãããããã¨ããããããã
void f( Base & base )
{
if ( /* baseã®æããªãã¸ã§ã¯ããDerivedã¯ã©ã¹ã®å ´å*/ )
{
// ç¹å¥ãªå¦ç
}
// å
±éã®å¦ç
}
æ¬æ¥ããã®ãããªå¦çã¯ãvirtualé¢æ°ã§è¡ãã¹ãã§ãããããããç¾å®ã«ã¯ãã©ããã¦ãããã®ãããªæ³¥èãã¦æ±ãã³ã¼ããæ¸ããªããã°ãªããªãå ´åãããããã®ãããªã©ããããããªãå ´åã®ããã«ãC++ã«ã¯ãåºæ¬ã¯ã©ã¹ã¸ã®ãã¤ã³ã¿ã¼ããªãã¡ã¬ã³ã¹ããå®ã¯æ´¾çã¯ã©ã¹ã®ãªãã¸ã§ã¯ããåç
§ãã¦ããå ´åã«éãããã£ã¹ãã§ããã¨ããæ©è½ãæä¾ããã¦ãããããããdynamic_castã§ããã
åçãªåãã§ãã¯ã使ãããã«ã¯ãdynamic_castã®ãªãã©ã³ãã®ã¯ã©ã¹ã¯ãããªã¢ã¼ãã£ãã¯åã§ãªããã°ãªããªããã¤ã¾ããå°ãªãã¨ãã²ã¨ã¤ã®virtualé¢æ°ãæã£ã¦ããªããã°ãªããªããããªã¢ã¼ãã£ãã¯åã®è©³ããå®ç¾©ã«ã¤ãã¦ã¯ãvirtualé¢æ°ãåç
§ã
ããããªãã©ã³ãã®åç
§ãããªãã¸ã§ã¯ãããå¤æå
ã®åã¨ãã¦æå®ããã¦ããæ´¾çã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã§ãã£ãå ´åãå¤æãããã¨ãã§ããã
struct Base { virtual void f() {} } ;
struct Derived : Base {} ;
void f(Base & base)
{ // baseã¯Derivedãæãã¦ããã¨ãã
Derived & ref = dynamic_cast<Derived &>(base) ;
Derived * ptr = dynamic_cast<Derived *>(&base) ;
}
å®å¼æ°ã«ãå¤æå
ã®åã§ã¯ãªããªãã¸ã§ã¯ãã渡ããå ´åãdynamic_castã®å¤æã¯å¤±æãããå¤æã失æããå ´åãå¤æå
ã®åããªãã¡ã¬ã³ã¹ã®å ´åãstd::bad_castãthrowããããå¤æå
ã®åããã¤ã³ã¿ã¼ã®å ´åãnullãã¤ã³ã¿ã¼ãè¿ãããã
struct Base { virtual void f() {} } ;
struct Derived : Base {} ;
int main()
{
Base base ;
// ãªãã¡ã¬ã³ã¹ã®å ´å
try
{
Derived & ref = dynamic_cast<Derived &>(base) ;
}
catch ( std::bad_cast )
{
// å¤æ失æ
// ãªãã¡ã¬ã³ã¹ã®å ´åãstd::bad_castãthrowããã
}
// ãã¤ã³ã¿ã¼ã®å ´å
Derived * ptr = dynamic_cast<Derived *>(&base) ;
if ( ptr == nullptr )
{
// å¤æ失æ
// ãã¤ã³ã¿ã¼ã®å ´åãnullãã¤ã³ã¿ã¼ãè¿ããã
}
}
åºæ¬ã¯ã©ã¹ã®ãã¤ã³ã¿ã¼ããªãã¡ã¬ã³ã¹ããå®éã¯ä½ãæãã¦ãããã¯ãå®è¡æã«ããåãããªãããã®ããã常ã«å¤æã«å¤±æããå¯è½æ§ãããããã®ãããdynamic_castã使ãå ´åã¯ã常ã«å¤æã失æãããããããªãã¨ããåæã®ãã¨ã«ãã³ã¼ããæ¸ããªããã°ãªããªãã
失æããã«å¤æã§ããå ´åã¨ããã®ã¯ããªãã©ã³ãã®æããªãã¸ã§ã¯ãã®æ¬å½ã®åããå¤æå
ã®åã®ãªãã¸ã§ã¯ãã§ããå ´åã§ããããã¢ã¯ã»ã¹ã§ããå ´åã§ããããªãã¸ã§ã¯ãã§ããï¼is aï¼å ´åã¨ããã®ã¯ãä¾ãã°ã
struct A { virtual void f(){} } ;
struct B : A {} ;
struct C : B {} ;
struct D : C {} ;
ãã®ãããªã¯ã©ã¹ããã£ãå ´åãDã¯ãCã§ãããBã§ãããAã§ãããå¾ã£ã¦ãDã®ãªãã¸ã§ã¯ãããAã¸ã®ãªãã¡ã¬ã³ã¹ã§ä¿æãã¦ããå ´åãDãCãBã®ãããã«ãå¤æã§ããã
int main()
{
D d ;
A & ref = d ;
// OK
// refã®æãã¦ãããªãã¸ã§ã¯ãã¯ãDãªã®ã§ãå¤æã§ããã
dynamic_cast<D &>(ref) ;
dynamic_cast<C &>(ref) ;
dynamic_cast<B &>(ref) ;
}
ã¢ã¯ã»ã¹ã§ããå ´åã¨ããã®ã¯ãå¤æå
ã®åãããpublicã§æ´¾çãã¦ããå ´åã§ããã
struct Base1 { virtual void f(){} } ;
struct Base2 { virtual void g(){} } ;
struct Base3 { virtual void h(){} } ;
struct Derived
: public Base1,
public Base2,
private Base3
{ } ;
int main()
{
Derived d ;
Base1 & ref = d ;
// OKãBase2ã¯publicãªã®ã§ãã¢ã¯ã»ã¹åºæ¥ã
dynamic_cast<Base2 &>(ref) ;
// å®è¡æã¨ã©ã¼ãBase3ã¯privateãªã®ã§ãã¢ã¯ã»ã¹åºæ¥ãªã
// std::bad_castãthrowãããã
dynamic_cast<Base3 &>(ref) ;
}
ãã®ä¾ã®å ´åãrefãåç
§ãããªãã¸ã§ã¯ãã¯ãDerivedåã§ããã®ã§ãBase3åã®ãµããªãã¸ã§ã¯ããæã£ã¦ããããBase3ããã¯ãprivateã§æ´¾çããã¦ããããã«ãã¢ã¯ã»ã¹ãããã¨ã¯ã§ããªãããã®ãããå¤æãããã¨ãåºæ¥ããstd::bad_castãthrowãããã
å¤æå
ã®åã¯ãvoidåã¸ã®ãã¤ã³ã¿ã¼ã¨ãããã¨ãã§ããããã®å ´åããªãã©ã³ãã®æãæ¬å½ã®ãªãã¸ã§ã¯ãã®ããã£ã¨ãæ´¾çãããã¯ã©ã¹ãæããã¤ã³ã¿ã¼ããvoidã¸ã®ãã¤ã³ã¿ã¼åã¨ãã¦ãè¿ãããã
struct Base { virtual void f(){} } ;
struct Derived1 : Base {} ;
struct Derived2 : Derived1 {} ;
int main()
{
Derived1 d1 ;
Base * d1_ptr = &d1 ;
// Derived1ãæããã¤ã³ã¿ã¼ã®å¤ããvoid *ã¨ãã¦è¿ããã
void * void_ptr1 = dynamic_cast<void *>(d1_ptr) ;
Derived1 d2 ;
Base * d2_ptr = &d2;
// Derived2ãæããã¤ã³ã¿ã¼ã®å¤ããvoid *ã¨ãã¦è¿ããã
void * void_ptr2 = dynamic_cast<void *>(d2_ptr) ;
}
ä¸è¬ã«ããã®æ©è½ã¯ãã¾ã使ããããã¨ããªãã ããã
dynamic_castã¯ããã®ä¸»ç®çã®æ©è½ã®ä»ã«ããã¯ã©ã¹ã¸ã®ãã¤ã³ã¿ã¼ããªãã¡ã¬ã³ã¹ã«éã£ã¦ããã£ã¹ããè¡ããã¨ãã§ããããã®æ©è½ã¯ãæ¨æºåå¤æã®ãã¤ã³ã¿ã¼ã®åå¤æã«ãã»ã¼ä¼¼ã¦ããããã®ãã£ã¹ãã¯ãstatic_castã§ãè¡ããã以ä¸ã®æ©è½ã«é¢ãã¦ã¯ãå®è¡æã®ã³ã¹ãã¯çºçããªãã
ãªãã©ã³ãã®åããå¤æå
ã®åã¨åãå ´åãå¼ã®çµæã®åã¯ãå¤æå
ã®åã«ãªãããã®æãconstã¨volatileãä»ãå ãããã¨ã¯ã§ããããæ¶ãå»ããã¨ã¯åºæ¥ãªãã
// åã¨å¼ãåãå ´åã®ä¾
struct C { } ;
int main()
{
C v ;
dynamic_cast<C &>(v) ;
dynamic_cast<C const &>(v) ; // constãä»ãå ãã
C const cv ;
dynamic_cast<C &>(cv) ; // ã¨ã©ã¼ãconstãæ¶ãå»ããã¨ã¯åºæ¥ãªã
// ãã¤ã³ã¿ã¼ã®å ´å
C * ptr = &v ;
dynamic_cast<C *>(ptr) ;
dynamic_cast<C const *>(ptr) ;
}
å¤æå
ã®åãåºæ¬ã¯ã©ã¹ã¸ã®ãªãã¡ã¬ã³ã¹ã§ããªãã©ã³ãã®åããæ´¾çã¯ã©ã¹ã¸ã®ãªãã¡ã¬ã³ã¹ã®å ´åãdynamic_castã®çµæã¯ãæ´¾çã¯ã©ã¹ã®ãã¡ã®åºæ¬ã¯ã©ã¹ãæããªãã¡ã¬ã³ã¹ã«ãªãããã¤ã³ã¿ã¼ã®å ´åããåæ§ã§ããã
struct Base {} ; // åºæ¬ã¯ã©ã¹
struct Derived : Base {} ; // æ´¾çã¯ã©ã¹
int main()
{
Derived d ;
Base & base_ref = dynamic_cast<Base &>(d) ;
Base * base_ptr = dynamic_cast<Base *>(&d) ;
}
typeid ( å¼ )
typeid ( åå )
typeidã¨ã¯ãå¼ãååã®ãåæ
å ±ãå¾ãããã®å¼ã§ãããåæ
å ±ã¯ãconst std::type_infoã®ãªãã¡ã¬ã³ã¹ã¨ããå½¢ã§è¿ããããstd::type_infoã«ã¤ãã¦ã®è©³ç´°ã¯ãRTTIï¼Run Time Type Informationï¼ãåç
§ãtypeidã使ãã«ã¯ãå¿
ãã<typeinfo>ãããã¼ã#includeããªããã°ãªããªãããã ããæ¬æ¸ã®ãµã³ãã«ã³ã¼ãã¯ãç´é¢ã®é½åä¸ãå¿
è¦ãªãããã¼ã®includeãçç¥ãã¦ãããã¨ãããã
typeidã®ãªãã©ã³ãã¯ãsizeofã«ä¼¼ã¦ãã¦ãå¼ã¨ååã®ä¸¡æ¹ãåããã¨ãã§ããã
#include <typeinfo>
int main()
{
// ååã®ä¾
typeid(int) ;
typeid( int * ) ;
// å¼ã®ä¾
int x = 0 ;
typeid(x) ;
typeid(&x) ;
typeid( x + x ) ;
}
typeidã®ãªãã©ã³ãã®å¼ããããªã¢ã¼ãã£ãã¯ã¯ã©ã¹åã®glvalueã§ãã£ãå ´åãå®è¡æãã§ãã¯ãåããçµæã®std::type_infoã表ãåæ
å ±ã¯ãå®è¡æã«æ±ºå®ããããåæ
å ±ã¯ããªãã¸ã§ã¯ãã®æãæ´¾çããã¯ã©ã¹ã®åã¨ãªãã
struct Base { virtual void f() {} } ;
struct Derived : Base {} ;
int main()
{
Derived d ;
Base & ref = d ;
// ãªãã¸ã§ã¯ãã®ãå®è¡æã®æ¬å½ã®åã表ãtype_infoãè¿ããã
std::type_info const & ti = typeid(d) ;
// true
ti == typeid(Derived) ;
// Derivedã表ãã人éã®èªããå®è£
ä¾åã®æåå
std::cout << ti.name() << std::endl ;
}
ãªãã©ã³ãã®å¼ã®åãããªã¢ã¼ãã£ãã¯ã¯ã©ã¹åã®glvalueã®å ´åã§ãnullãã¤ã³ã¿ã¼ãåç
§ããå ´åã¯ãstd::bad_typeidãæããããã
struct Base { virtual void f() {} } ;
struct Derived : Base {} ;
int main()
{
// ptrã®å¤ã¯nullãã¤ã³ã¿ã¼
Base * ptr = nullptr ;
try
{
typeid( *ptr ) ; // å®è¡æã¨ã©ã¼
}
catch ( std::bad_typeid )
{
// ä¾å¤ãæãããã¦ãããã«å¦çã移ã
}
}
ãªãã©ã³ãã®å¼ã®åããããªã¢ã¼ãã£ãã¯ã¯ã©ã¹åã§ãªãå ´åã¯ãstd::type_infoã表ãåæ
å ±ã¯ãã³ã³ãã¤ã«æã«æ±ºå®ãããã
// intåã表ãtype_info
typeid(0) ;
// doubleåã表ãtype_info
typeid(0.0) ;
int f() {}
// intåã表ãtype_info
typeid( f() ) ;
ãã®éãlvalueããrvalueã¸ã®åå¤æãé
åãããã¤ã³ã¿ã¼ã¸ã®åå¤æãé¢æ°ãããã¤ã³ã¿ã¼ã¸ã®åå¤æã¯è¡ãããªãã
// é
åãããã¤ã³ã¿ã¼ã¸ã®åå¤æã¯è¡ãããªã
int a[10] ;
// åæ
å ±ã¯ãint [10]
// int *ã§ã¯ãªã
typeid(a) ;
// é¢æ°ãããã¤ã³ã¿ã¼ã¸ã®åå¤æã¯è¡ãããªã
void f() {}
// åæ
å ±ã¯ãvoid (void)
// void (*)(void)ã§ã¯ãªãã
typeid(f) ;
ãããã®æ¨æºåå¤æã¯ãC++ã§ã¯ãé常ã«å¤ãã®å ´æã§ãæé»ã®ãã¡ã«è¡ããã¦ããã®ã§ããã¾ãæèããªãããã¨ãã°ããã³ãã¬ã¼ãã®å®å¼æ°ãæ¨å®ããä¸ã§ã¯ããããã®å¤æãè¡ãããã
// å®å¼æ°ã®åãã表示ãã¦ãããã¯ãã®ä¾¿å©ãªé¢æ°
template < typename T >
void print_type_info(T)
{
std::cout << typeid(T).name() << std::endl ;
}
void f() { }
int main()
{
int a[10] ;
// int [10]
std::cout << typeid(a).name() << std::endl ;
// int *
print_type_info(a) ;
// void (void)
std::cout << typeid(f).name() << std::endl ;
// void (*)(void)
print_type_info(f) ;
}
std::type_info::name()ã®è¿ãæååã¯å®è£
ä¾åã ããä»ãC++ã®ææ³ã¨åãããã«åã表示ããã¨ä»®å®ããã¨ããã®ãããªåºåã«ãªããC++ã§ã¯ãå¤ãã®å ´é¢ã§ãæé»ã®ãã¡ã«ããããä¸ã¤ã®åå¤æãè¡ãããã®ã§ããã®ãããªå·®ç°ãçããã
ãªãã©ã³ãããååã®å ´åã¯ãstd::type_infoã¯ããã®åã表ããã»ãã®ä¸ä¾ããããã¨ã
int main()
{
typeid( int ) ; // intå
typeid( int * ) ; // intã¸ã®ãã¤ã³ã¿ã¼å
typeid( int & ) ; // intã¸ã®lvalueãªãã¡ã¬ã³ã¹å
typeid( int [2] ) ; // é
åå
typeid( int (*)[2] ) ; // é
åã¸ã®ãã¤ã³ã¿ã¼å
typeid( int (int) ) ; // é¢æ°å
typeid( int (*)(int) ); // é¢æ°ã¸ã®ãã¤ã³ã¿ã¼å
}
ãªãã©ã³ãã®å¼ãååã®ããããã¬ãã«ï¼top-levelï¼ã®CV修飾åã¯ãç¡è¦ãããã
int main()
{
// ãããã¬ãã«ã®CV修飾åã¯ç¡è¦ããã
typeid(const int) ; // int
// å½ç¶ãåæ
å ±ã¯çãã
typeid(const int) == typeid(int) ; // true
// ååãå¼ãåã
int i = 0 ; const int ci = 0;
typeid(ci) ; // int
typeid(ci) == typeid(i) ; // true
// ããã¯ãããã¬ãã«ã®CV修飾å
typeid(int * const) ; // int *
// 以ä¸ã¯ãããã¬ãã«ã®CV修飾åã§ã¯ãªã
typeid(const int *) ; // int const *
typeid(int const *) ; // int const *
}
static_cast< åå >( å¼ )
static_castã¯ãå®ã«å¤ãã®éçãªå¤æãã§ããããã®æ¦è¦ã¯ãæ¨æºåå¤æã¨ãã®éå¤æãã¦ã¼ã¶ã¼å®ç¾©ã®å¤æããªãã¡ã¬ã³ã¹ããã¤ã³ã¿ã¼ã«ãããå¤æãªã©ãæ¯è¼çå®å
¨ãªãã£ã¹ãã§ããã以ä¸ã«static_castã®è¡ããå¤æãåæãããããããã丸æè¨ãã¦ããå¿
è¦ã¯ãªãããããã©ã®ãã£ã¹ãã使ããè¿·ã£ãå ´åã¯ãstatic_castã使ã£ã¦ããã°ãã¾ãééãã¯ãªããstatic_castãã³ã³ãã¤ã«ã¨ã©ã¼ã¨ãªããã£ã¹ãã¯ã大æµãå®è£
ä¾åã§å±éºãªãã£ã¹ãã§ããã
static_castã«ãããã£ã¹ããã©ã®ããã«è¡ããããã¯ãããããã以ä¸ã®ãããªé åºã§å¤å®ããããæ¡ä»¶ã«åãå¤ææ¹æ³ãè¦ã¤ãã£ãæç¹ã§ãããããå
ã«è¡ããã¨ã¯ãªããããã¯ãå®å
¨ãªstatic_castã®å®ç¾©ã§ã¯ãªããåãããããã®ããçããæåãããã
static_cast<T>(v)ã®çµæã¯ããªãã©ã³ãvãå¤æå
ã®åTã«å¤æãããã®ã¨ãªããå¤æå
ã®åãlvalueãªãã¡ã¬ã³ã¹ãªãã°çµæã¯lvalueãrvalueãªãã¡ã¬ã³ã¹ãªãã°çµæã¯xvalueããã以å¤ã®çµæã¯prvalueã¨ãªããstatic_castã¯ãconstã¨volatileãæ¶ãå»ããã¨ã¯ã§ããªãã
ãªãã©ã³ãã®åãåºæ¬ã¯ã©ã¹ã§ãå¤æå
ã®åãæ´¾çã¯ã©ã¹ã¸ã®ãªãã¡ã¬ã³ã¹ã®å ´åããããæ¨æºåå¤æã§ãæ´¾çã¯ã©ã¹ã®ãã¤ã³ã¿ã¼ãããåºæ¬ã¯ã©ã¹ã®ãã¤ã³ã¿ã¼ã¸ã¨å¤æã§ããå ´åããã£ã¹ãã§ããã
struct Base {} ;
struct Derived : Base {} ;
void f(Base & base)
{
// Derived *ããBase *ã«æ¨æºåå¤æã§å¤æã§ããã®ã§ããã£ã¹ãã§ãã
Derived & derived = static_cast<Derived &>(base) ;
}
ãã ããããã«ã¯å®è¡æãã§ãã¯ããªãã®ã§ãbaseãæ¬å½ã«Derivedã®ãªãã¸ã§ã¯ããåç
§ãã¦ããªãã£ãå ´åãåä½ã¯æªå®ç¾©ã§ããã
glvalueã®ãªãã©ã³ãã¯ãrvalueãªãã¡ã¬ã³ã¹ã«åå¤æã§ããã
int main()
{
int x = 0 ;
static_cast<int &&>(x) ;
}
ãããstatic_cast<T>(e) ã¨ããå¼ã§ãT t(e); ã¨ãã宣è¨ãã§ããå ´åããªãã©ã³ãã®å¼eã¯ãå¤æå
ã®åTã«å¤æã§ããããã®å ´åãä¸æãªãã¸ã§ã¯ãã宣è¨ãã¦ãããããã®ã¾ã¾ä½¿ãã®ã¨ãåãæå³ã«ãªãã
// short t(0) ã¯å¯è½ãªã®ã§å¤æã§ãã
static_cast<short>(0) ;
// float t(0) ã¯å¯è½ãªã®ã§å¤æã§ãã
static_cast<float>(0) ;
æ¨æºåå¤æã®éå¤æãè¡ããã¨ãã§ããããã ããããã¤ãã®å¤æã¯ãéå¤æãè¡ããªããããã«ã¯ãlvalueããrvalueã¸ã®åå¤æãé
åãããã¤ã³ã¿ã¼ã¸ã®åå¤æãé¢æ°ãããã¤ã³ã¿ã¼ã¸ã®åå¤æï¼Function-to-pointer conversionï¼ããã¤ã³ã¿ã¼ãé¢æ°ãã¤ã³ã¿ã¼ããnullãã¤ã³ã¿ã¼ã¸ã®å¤æããããã
å¤æå
ã®åã«ãvoidãæå®ãããã¨ãã§ããããã®å ´åãstatic_castã®çµæã¯voidã§ããããªãã©ã³ãã®å¼ã¯è©ä¾¡ãããã
int main()
{
static_cast<void>( 0 ) ;
static_cast<void>( 1 + 1 ) ;
}
æ´æ°åã¨scoped enumåã¯ãstatic_castã使ããã¨ã§ãæ示çã«å¤æãããã¨ãã§ããããã®å ´åãå¤æå
ã®åã§ããªãã©ã³ãã®å¤ã表ç¾ã§ããå ´åã¯ãå¤ãä¿æããããå¤ã表ç¾ã§ããªãå ´åã®æåã¯ãè¦å®ããã¦ããªãã
int main()
{
enum struct A { value = 1 } ;
enum struct B { value = 1 } ;
int x = static_cast<int>( A::value ) ;
A a = static_cast<A>(1) ;
B b = static_cast<B>( A::value ) ;
}
æ´¾çã¯ã©ã¹ã¸ã®ãã¤ã³ã¿ã¼ãããåºæ¬ã¯ã©ã¹ã¸ã®ãã¤ã³ã¿ã¼ã«ãã£ã¹ãã§ããã
struct Base {} ;
struct Derived : Base {} ;
Derived d ;
Base * ptr = static_cast<Base *>(&d) ;
voidã¸ã®ãã¤ã³ã¿ã¼ã¯ãä»ã®åã¸ã®ãã¤ã³ã¿ã¼ã«å¤æã§ãããããåã¸ã®ãã¤ã³ã¿ã¼ãããvoidã¸ã®ãã¤ã³ã¿ã¼ã«ãã£ã¹ãããããã®ã¾ã¾ãããåã¸ã®ãã¤ã³ã¿ã¼ã«ãã£ã¹ããããªããããå ´åããã®å¤ã¯ä¿æãããã
int main()
{
int x = 0 ;
int * ptr = &x ;
// void *ã¸ã®å¤æã¯ãæ¨æºåå¤æã§è¡ããã®ã§ããã£ã¹ãã¯ãªãã¦ãããã
void * void_ptr = static_cast<void *>(ptr) ;
// ãã£ã¹ããå¿
è¦
ptr = static_cast<int *>(void_ptr) ;
*ptr ; // ãã¤ã³ã¿ã¼ã®å¤ã¯ä¿æãããã®ã§ãxãæ£ããåç
§ãã
}
reinterpret_cast < åå > ( å¼ )
reinterpret_castã¯ãå¼ã®å¤ããã®ã¾ã¾ãä»ã®åã«å¤æãããã£ã¹ãã§ããããã¤ã³ã¿ã¼ã¨æ´æ°ã®éã®å¤æããããåã¸ã®ãã¤ã³ã¿ã¼ãå
¨ãå¥ã®åã¸ã®ãã¤ã³ã¿ã¼ã«å¤æããã¨ãã£ããã¨ãã§ãããreinterpret_castã使ãã°ãå¤ããã®ã¾ã¾ã«ãã¦ãåãå¤æãããã¨ãã§ãããå¤æããçµæããã®å¤ããå¤æå
ã®åã¨ãã¦ãã®ã¾ã¾ä½¿ãããã©ãããªã©ã¨ãã£ããã¨ã¯ãã»ã¨ãã©è¦å®ããã¦ããªããå
ã®å¤ããã®ã¾ã¾ä¿æã§ãããã©ãããåãããªããããæ
ãreinterpret_castã¯ãå±éºãªãã£ã¹ãã§ããã
å¤ãã®å®è£
ã§ã¯ãreinterpret_castã«ã¯ãä½ããã®å
·ä½çã§å®ç¨çãªæå³ããããç¾å®ã®C++ãå¿
è¦ã¨ãããç°å¢ã§ã¯ãreinterpret_castã使ããªããã°ãªããªããã¨ããå¤ããããããããreinterpret_castã使ã£ãæç¹ã§ããã®ã³ã¼ãã¯å®è£
ä¾åã§ãããå
·ä½çã«æå³ãå®ç¾©ããããã®ç°å¢ã§ããåããªãã¨ãããã¨ãã常ã«æèããã¹ãã§ããã
reinterpret_castã§ã¯ãconstãvolatileãæ¶ãå»ããã¨ã¯ã§ããªãã
reinterpret_castã§ã§ããå¤æãã以ä¸ã«åæããã
ãã¤ã³ã¿ã¼åã¨æ´æ°åã®éã®åå¤æ
ããåã¸ã®ãã¤ã³ã¿ã¼åããæ´æ°åã¸ã®ãã£ã¹ãããããã¯ãã®éã«ãæ´æ°åãenumåãããã¤ã³ã¿ã¼åã¸ã®ãã£ã¹ããè¡ãããæ´æ°åã¯ããã¤ã³ã¿ã¼ã®å¤ããã®ã¾ã¾ä¿æã§ããã»ã©å¤§ãããªããã°ãªããªããã©ã®æ´æ°åãªãã°ååã«å¤§ããã®ããããæ´æ°åãååã«å¤§ãããªããã°ã©ããªãã®ããªã©ã¨ãããã¨ã¯ãå®ç¾©ããã¦ããªãã
int main()
{
int x = 0 ;
int * ptr = &x ;
// ãã¤ã³ã¿ã¼ããæ´æ°ã¸ã®ãã£ã¹ã
int value = reinterpret_cast<int>(ptr) ;
// æ´æ°ãããã¤ã³ã¿ã¼ã¸ã®ãã£ã¹ã
ptr = reinterpret_cast<int *>(value) ;
}
ãããã®ãã£ã¹ãã«ã¤ãã¦ã®æåã¯ãã»ã¨ãã©ãå®è£
ä¾åã§ããããã¾ã説æã§ãããã¨ã¯ãªãã
ãããå¤æå
ã®æ´æ°åãããã¤ã³ã¿ã¼ã®å¤ããã¹ã¦è¡¨ç¾ã§ããã¨ãããªãã°ãåã³ãã¤ã³ã¿ã¼åã«ãã£ã¹ããç´ããæããã¤ã³ã¿ã¼ã¯åãå¤ãä¿æããã¨è¦å®ããã¦ãããããããintåããã¤ã³ã¿ã¼ã®å¤ããã¹ã¦è¡¨ç¾ã§ããã¨ããä¿è¨¼ã¯ãªããunsigned intã§ãããã¨ãlong intã§ãããã¨long long intã§ãããã¨ããã®ãããªä¿è¨¼ã¯ãªããå¾ã£ã¦ãä¸è¨ã®ã³ã¼ãã§ãptrãåãå¤ãä¿ã¤ãã©ããã¯ãå®è£
ä¾åã§ããã
ç°ãªããã¤ã³ã¿ã¼åã®éã®åå¤æ
ããåã¸ã®ãã¤ã³ã¿ã¼ã¯ãã¾ã£ããå¥ã®åã¸ã®ãã¤ã³ã¿ã¼ã«å¤æã§ããããã¨ãã°ãint *ããshort *ãªã©ã¨ãã£ãå¤æãã§ããã
int main()
{
int x = 0 ;
int * int_ptr = &x ;
// int * ããshort *ã¸ã®ãã£ã¹ã
short * short_ptr = reinterpret_cast<short *>(int_ptr) ;
}
ããã«ã¤ãã¦ããæåã¯å®è£
ä¾åã§ãããç¹ã«èª¬æã§ãããã¨ã¯ãªãããã¨ãã°ãä¸è¨ã®ã³ã¼ãã§ãshort_ptrãåç
§ããå ´åã©ããªãã®ãã¨ãããã¨ããå
¨ãè¦å®ããã¦ããªããããå®è£
ã§ã¯ãåé¡ãªããintåã®ã¹ãã¬ã¼ã¸ããããããshortåã®ã¹ãã¬ã¼ã¸ã¨ãã¦ä½¿ããã¨ãã§ãããããããªããããå®è£
ã§ã¯ãåç
§ããç¬éã«ããã°ã©ã ãã¯ã©ãã·ã¥ãããããããªãã
ç°ãªããªãã¡ã¬ã³ã¹åã®éã®åå¤æ
ç°ãªããã¤ã³ã¿ã¼åã®éã®åå¤æã«ä¼¼ã¦ããããç°ãªããªãã¡ã¬ã³ã¹åã®å¤æããããã¨ãã§ãããä¾ãã°ãint &ããshort &ãªã©ã¨ãã£ãå¤æãã§ããã
int main()
{
int x = 0 ;
// int & ããshort &ã¸ã®ãã£ã¹ã
short & short_ref = reinterpret_cast<short &>(x) ;
}
ç°ãªããã¤ã³ã¿ã¼åã®éã®åå¤æã¨åãã§ãããã«ã¤ãã¦ããå
·ä½çãªæå³ã¯å®è£
ä¾åã§ããã
ç°ãªãã¡ã³ãã¼ãã¤ã³ã¿ã¼ã®éã®åå¤æ
ç°ãªãã¡ã³ãã¼ãã¤ã³ã¿ã¼ã¸å¤æãããã¨ãã§ããã
struct A { int value ; } ;
struct B { int value ; } ;
int main()
{
int B::* ptr = reinterpret_cast<int B::*>(&A::value) ;
}
æå³ã¯ãå®è£
ä¾åã§ããã
ç°ãªãé¢æ°ãã¤ã³ã¿ã¼åã®éã®åå¤æ
ããé¢æ°ãã¤ã³ã¿ã¼ã¯ãå¥ã®åã®é¢æ°ãã¤ã³ã¿ã¼ã«ãã£ã¹ãã§ãããããããªããæå³ã¯å®è£
ä¾åã§ãããããããããªããã¨ããã®ã¯å®ã«ææ§ãªè¡¨ç¾ã ãããã¨ãå®å
¨ã«è¦æ ¼æºæ ãªå®è£
ã§ãã£ã¦ãããã®æ©è½ããµãã¼ããã義åããªãã¨ããæå³ã§ããã
void f(int) {}
int main()
{
// void (short)ãªé¢æ°ã¸ã®ãã¤ã³ã¿ã¼å
using type = void (*)(short) ;
// é¢æ°ãã¤ã³ã¿ã¼ã®åå¤æ
type ptr = reinterpret_cast<type>(&f) ;
}
ãã®å¤æãã©ãããæå³ãæã¤ã®ããä¾ãã°ãå¤æããçµæã®é¢æ°ãã¤ã³ã¿ã¼ã¯ãé¢æ°å¼ã³åºãã§ããã®ããã§ããã¨ãã¦ãä¸ä½ã©ãããæå³ã«ãªãã®ãããªã©ã¨ãããã¨ã¯ä¸åè¦å®ããã¦ããªãã
reinterpret_castã«ã¯ãã§ããªããã¨
reinterpret_castãè¡ãããã£ã¹ãã¯ãä¸è¨ã«ãã¹ã¦åæããããã以å¤ã®å¤æã¯ãreinterpret_castã§ã¯è¡ããã¨ãã§ããªããããã¯ãããããreinterpret_castã®ç®çããå±éºã§å®è£
ä¾åãªãã£ã¹ãã®ã¿ãåé¢ããã¨ããç®çã«ããã®ã§ããã以å¤ã®å¤æã¯ãããã¦è¡ããªãããã«ãªã£ã¦ããã
int main()
{
short value = 0 ;
// OKãæ¨æºåå¤æã«ããæé»ã®åå¤æ
int a = value ;
// OKãstatic_castã«ããæ示çãªåå¤æ
int b = static_cast<int>(value) ;
// ã¨ã©ã¼
// reinterpret_castã§ã¯ããã®åå¤æããµãã¼ããã¦ããªã
int c = reinterpret_cast<int>(value) ;
}
const_cast < åå > ( å¼ )
const_castã¯ãconstã¨volatileãç°ãªãåã®éã®åå¤æãè¡ããconstãvolatileãåãé¤ããã¨ããä»ãå ãããã¨ãã§ããã
int main()
{
int const x = 0 ;
// ã¨ã©ã¼ãconstãåãé¤ããã¨ã¯ã§ããªãã
int * error1 = &x ;
int * error2 = static_cast<int *>(&x) ;
// OKããã¤ã³ã¿ã¼ã®ä¾
int * ptr = const_cast<int *>(&x) ;
// OKããªãã¡ã¬ã³ã¹ã®ä¾
int & ref = const_cast<int &>(x) ;
// constãä»ãå ãããã¨ãã§ããã
int y = 0 ;
int const * cptr = const_cast<int const *>(&y) ;
}
ãã¤ã³ã¿ã¼ã¸ã®ãã¤ã³ã¿ã¼ã§ãã£ã¦ããããããã®constãåãé¤ããã¨ãã§ããã
int main()
{
int const * const * const * const c = nullptr ;
int *** ptr = const_cast<int ***>(c) ;
}
const_castã¯ãconstãvolatileã®ã¿ãåãé¤ããã¾ãã¯ä»ãå ãããã£ã¹ãã®ã¿ãè¡ããããã以å¤ã®åå¤æãè¡ããã¨ã¯ã§ããªãã
int main()
{
int const x = 0 ;
// ã¨ã©ã¼ãconst以å¤ã®åå¤æãè¡ã£ã¦ããã
short * ptr = const_cast<short *>(&x) ;
}
ã§ã¯ãconstãåãé¤ãã¨åæã«ãä»ã®åå¤æãè¡ãªãããå ´åã¯ã©ããããã¨ããã¨ãstatic_castããreinterpret_castãä½µç¨ããã
int main()
{
int const x = 0 ;
short * ptr1 =
static_cast<short *>(
static_cast<void *>(
const_cast<int *>(&x)
)
) ;
short * ptr2 = reinterpret_cast<short *>(const_cast<int *>(&x)) ;
}
const_castã¯ãåºæ¬çã«ãã»ã¨ãã©ã®constããã£ã¹ããããã¨ãã§ãããããã£ã¹ãã§ããªãconstãåå¨ããããã¨ãã°ãé¢æ°ãã¤ã³ã¿ã¼ãã¡ã³ãã¼é¢æ°ãã¤ã³ã¿ã¼ã«é¢ããconstãåãé¤ããã¨ã¯ã§ããªããé¢æ°ã¸ã®ãªãã¡ã¬ã³ã¹ãåæ§ã§ããã
void f( int ) {}
int main()
{
using type = void (*)(int) ;
type const ptr = nullptr ;
// ã¨ã©ã¼ãé¢æ°ãã¤ã³ã¿ã¼ã¯ãã£ã¹ãã§ããªã
type p = const_cast<type>(ptr) ;
}
ãã¡ãããé¢æ°ã®ä»®å¼æ°ã«å¯¾ããconstããã£ã¹ããããã¨ããconstãªã¡ã³ãã¼é¢æ°ãéconstãªã¡ã³ãã¼é¢æ°ã«ãã£ã¹ããããã¨ãªã©ãã§ããªãã
åé
å¼ã¯ããªãã©ã³ããã²ã¨ã¤ããåããªããã¨ãããããå¼ã°ãã¦ãããåé
å¼ã®è©ä¾¡é åºã¯ãã¹ã¦ããå³ããå·¦ãã§ããã
åé
æ¼ç®åã¨ããã«ãã´ãªã¼ã«ã¯ãå
ã¤ã®ç°ãªãæ¼ç®åãã¾ã¨ãããã¦ããã*ã&ã+ã-ã!ã~ã§ããã
* åé
æ¼ç®åã¯ãåç
§ï¼indirectionï¼ã§ããããªãã©ã³ãã¯ããªãã¸ã§ã¯ãã¸ã®ãã¤ã³ã¿ã¼ã§ãªããã°ãªããªãããªãã©ã³ãã®åãããTã¸ã®ãã¤ã³ã¿ã¼ãã§ããã¨ããã¨ãå¼ã®çµæã¯ãlvalueã®Tã§ããã
& æ¼ç®åã¯ããªãã©ã³ãã®ãã¤ã³ã¿ã¼ãå¾ãããªãã©ã³ãã®åãTã§ããã¨ããã¨ãçµæã¯ãprvalueã®Tã¸ã®ãã¤ã³ã¿ã¼ã§ããã& æ¼ç®åã¯ããªãã¸ã§ã¯ãã ãã§ã¯ãªããé¢æ°ã«ãé©ç¨ã§ããã
int main()
{
int x = 0 ;
// & æ¼ç®å
// å¤æ°xã®ãªãã¸ã§ã¯ãã¸ã®ãã¤ã³ã¿ã¼ãå¾ãã
int * ptr = &x ;
// * æ¼ç®å
// ãã¤ã³ã¿ã¼ãåç
§ãã
*ptr ;
}
åé
æ¼ç®åã®+ã¨-ã¯ããªãã©ã³ãã®ç¬¦å·ãæå®ããæ¼ç®åã§ããã
+ åé
æ¼ç®åã¯ããªãã©ã³ãã®å¤ãããã®ã¾ã¾è¿ãããªãã©ã³ãã®åã«ã¯ãæ°å¤åãéscoped enumåããã¤ã³ã¿ã¼åã使ãããçµæã¯prvalueã§ããã
int main()
{
int x = +0 ; // xã¯0
+x ; // çµæã¯0
int * ptr = nullptr ;
+ptr ; // çµæã¯ptrã®å¤
}
ãã ãããªãã©ã³ãã«ã¯ãæ´æ°ã®ããã¢ã¼ã·ã§ã³ãé©ç¨ãããã®ã§ããªãã©ã³ãã®åãcharãshortçã®å ´åãintåã«ãªãã
short x = 0 ;
+x ; // intåã®0
- åé
æ¼ç®åã¯ããªãã©ã³ãã®å¤ããè² æ°ã«ãã¦è¿ãããªãã©ã³ãã®åã«ã¯ãæ°å¤åã¨éscoped enumåã使ããã+ åé
æ¼ç®åã¨åããããªãã©ã³ãã«ã¯æ´æ°ã®ããã¢ã¼ã·ã§ã³ãé©ç¨ãããã
-0 ; // 0
-1 ; // -1
- -1 ; // +1
- åé
æ¼ç®åããunsignedãªæ´æ°åã«ä½¿ãããå ´åã®æåã¯ãæ確ã«å®ç¾©ããã¦ããããªãã©ã³ãã®unsignedãªæ´æ°åã®ãããæ°ãnã¨ãããå¼ã®çµæã¯ã2nããããªãã©ã³ãã®å¤ãå¼ããçµæã®å¤ã«ãªãã
å
·ä½çãªä¾ãæããããã«ãä»ãunsigned intåã16ãããã ã¨ä»®å®ããã
// unsigned intåã¯16bitã§ããã¨ããã
unsigned int x = 1 ;
// result = 216 - 1 = 65536 - 1 = 65535
unsigned int result = -x ;
x = 100 ;
// result = 216 - 100 = 65536 - 100 = 65436
result = -x ;
! æ¼ç®åã¯ããªãã©ã³ããboolã«å¤æãããã®å¦å®ãè¿ããã¤ã¾ãããªãã©ã³ããtrueã®å ´åã¯falseã«ãfalseã®å ´åã¯trueã«ãªãã
!true ; // false
!false ; // true
int x = 0 ;
!x ; // 0ã¯falseã«å¤æãããããã®å¦å®ãªã®ã§ãçµæã¯true
~ æ¼ç®åã¯ããããå転ã¨ãå¼ã°ãã¦ããããªãã©ã³ãã«ã¯ãæ´æ°åã¨éscoped enumåã使ãããå¼ã®çµæã¯ããªãã©ã³ãã®1ã®è£æ°ã¨ãªããããªãã¡ããªãã©ã³ãã®åããããå転ãããå¤ã¨ãªãããªãã©ã³ãã«ã¯æ´æ°ã®ããã¢ã¼ã·ã§ã³ãé©ç¨ãããã
int x = 0 ;
// ãããåã®åããããå転ãã
~x ;
++ å¼
-- å¼
ããã§ã¯ãåç½®å¼ã®ã¤ã³ã¯ãªã¡ã³ãã¨ãã¯ãªã¡ã³ãã«ã¤ãã¦è§£èª¬ãããå¾ç½®å¼ã®ã¤ã³ã¯ãªã¡ã³ãã¨ãã¯ãªã¡ã³ããåç
§ã
åç½®å¼ã®++ æ¼ç®åã¯ããªãã©ã³ãã«1ãå ç®ãã¦ããã®çµæããã®ã¾ã¾è¿ãããªãã©ã³ãã¯æ°å¤åããã¤ã³ã¿ã¼åã§ãå¤æ´å¯è½ãªlvalueã§ãªããã°ãªããªããå¼ã®çµæã¯lvalueã«ãªãã
åç½®å¼ã®-- æ¼ç®åã¯ããªãã©ã³ããã1ãæ¸ç®ããããã以å¤ã¯ã++æ¼ç®åã¨åãããã«åãã
int x = 0 ;
int result = ++x ;
// ããã§ãresult = 1, x = 1
sizeof ( æªè©ä¾¡å¼ )
sizeof ( åå )
sizeof ... ( èå¥å )
sizeofã¨ã¯ããªãã©ã³ãã表ç¾ãããªãã¸ã§ã¯ãã®ãã¤ãæ°ãè¿ãæ¼ç®åã§ããããªãã©ã³ãã¯ãæªè©ä¾¡å¼ãååã«ãªãã
ãªãã©ã³ãã«ååãæå®ããå ´åãsizeofæ¼ç®åã¯ãåã®ãªãã¸ã§ã¯ãã®ãã¤ãæ°ãè¿ããsizeof(char)ãsizeof(signed char)ãsizeof(unsigned char)ã¯ã1ãè¿ãããã以å¤ã®ããããåã®ãµã¤ãºã¯ãå®è£
ã«ãã£ã¦å®ç¾©ãããããã¨ãã°ãsizeof(bool)ãsizeof(char16_t)ãsizeof(char32_t)ã®ãµã¤ãºããè¦æ ¼ã§ã¯æ±ºãããã¦ããªãã
// 1
sizeof(char) ;
// intåã®ãªãã¸ã§ã¯ãã®ãµã¤ãº
sizeof(int) ;
ãªãã©ã³ãã«å¼ãæå®ããå ´åããã®å¼ã®çµæã®åã®ãªãã¸ã§ã¯ãã®ãã¤ãæ°ãè¿ããå¼ã¯è©ä¾¡ãããªããlvalueããrvalueã¸ã®åå¤æãé
åãããã¤ã³ã¿ã¼ã¸ã®åå¤æãé¢æ°ãããã¤ã³ã¿ã¼ã¸ã®åå¤æã¯è¡ãããªãã
int f() ;
// intåã®ãªãã¸ã§ã¯ãã®ãµã¤ãº
sizeof( f() ) ;
// intåã®ãªãã¸ã§ã¯ãã®ãµã¤ãº
sizeof( 1 + 1 ) ;
é¢æ°å¼ã³åºãã®å¼ã®çµæã®åã¯ãé¢æ°ã®æ»ãå¤ã®åã«ãªãã
ãªãã©ã³ãã«ã¯ãé¢æ°ã¨ä¸å®å
¨åã使ããã¨ã¯ã§ããªããé¢æ°ã¯ããããããªãã¸ã§ã¯ãã§ã¯ãªãããä¸å®å
¨åã¯ããã®ãµã¤ãºã決å®ã§ããªãããã ããé¢æ°ãã¯ä½¿ããªãããé¢æ°å¼ã³åºãã¯ãé¢æ°ãã§ã¯ãªãã®ã§ä½¿ãããã¾ããé¢æ°ãã¤ã³ã¿ã¼ã«ã使ããã
int f() ;
struct Incomplete ;
// é¢æ°å¼ã³åºãã¯ãé¢æ°ãã§ã¯ãªã
// sizeof(int) ã¨åã
sizeof( f() ) ;
// é¢æ°ãã¤ã³ã¿ã¼ã¯ãªãã¸ã§ã¯ãã§ããã®ã§ã使ãã
// sizeof ( int (*)(void) ) ã¨åã
sizeof( &f ) ;
// ã¨ã©ã¼ãé¢æ°ã使ããã¨ã¯ã§ããªã
sizeof( f ) ;
// ã¨ã©ã¼ãä¸å®å
¨åã使ããã¨ã¯ã§ããªã
sizeof( Incomplete ) ;
ãªãã©ã³ãããªãã¡ã¬ã³ã¹åã®å ´åãåç
§ãããåã®ãªãã¸ã§ã¯ãã®ãµã¤ãºã«ãªãã
void f( int & ref )
{
// sizeof(int)ã¨åã
sizeof(int &) ;
sizeof(int &&) ;
sizeof( ref ) ;
}
ãªãã©ã³ããã¯ã©ã¹åã®å ´åãã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã®ãã¤ãæ°ã«ãªããããã«ã¯ãã¢ã©ã¤ã¡ã³ãã®èª¿æ´ããé
åã®è¦ç´ ã¨ãã¦ä½¿ããããã«ããããã®å®è£
ä¾åã®ããã£ã³ã°ãªã©ãå«ã¾ãããã¯ã©ã¹åã®ãµã¤ãºã¯ãå¿
ã1以ä¸ã«ãªããããã¯ããµã¤ãºã0ã§ã¯ããã¤ã³ã¿ã¼ã®æ¼ç®ãªã©ã«å·®ãæ¯ããããã§ããã
ãªãã©ã³ããé
ååã®å ´åãé
åã®ãã¤ãæ°ã«ãªããããã¯ã¤ã¾ããè¦ç´ ã®åã®ãµã¤ãºãÃãè¦ç´ æ°ã¨ãªãã
// sizeof(int) * 10 ã¨åã
sizeof( int [10] ) ;
char a[10] ;
// sizeof(char) * 10 = 1 * 10 = 10
sizeof( a ) ;
// ãã®åã¯é
åã§ã¯ãªããchar
// sizeof(char)ã¨åã
sizeof( a[0] ) ;
sizeof...ã¯ããªãã¸ã§ã¯ãã®ãã¤ãæ°ã¨ã¯ãä½ã®é¢ä¿ããªããsizeof...ã®ãªãã©ã³ãã«ã¯ããã©ã¡ã¼ã¿ã¼ããã¯ã®èå¥åãæå®ã§ãããsizeof...æ¼ç®åã¯ããªãã©ã³ãã®ãã©ã¡ã¼ã¿ã¼ããã¯ã®å¼æ°ã®æ°ãè¿ããsizeof...æ¼ç®åã®çµæã¯å®æ°ã§ãåã¯std::size_tã§ããã
#include <cstddef>
#include <iostream>
template < typename... Types >
void f( Types... args )
{
std::size_t const t = sizeof...(Types) ;
std::size_t const a = sizeof...(args) ;
std::cout << t << ", " << a << std::endl ;
}
int main()
{
f() ; // 0, 0
f(1,2,3) ; // 3, 3
f(1,2,3,4,5) ; // 5, 5
}
確ä¿é¢æ°ã¨è§£æ¾é¢æ°ã®å
·ä½çãªå®è£
æ¹æ³ã«ã¤ãã¦ã¯ãåçã¡ã¢ãªã¼ç®¡çãåç
§ã
::opt new åå newåæååopt
::opt new ( å¼ãªã¹ã ) åå newåæååopt
newã«å¿
è¦ãªå®£è¨ã®ä¸é¨ã¯ã<new>ãããã¼ã§å®ç¾©ããã¦ããã®ã§ã使ãéã¯ããããincludeããªããã°ãªããªãã
newå¼ã¯ãååã®ãªãã¸ã§ã¯ããçæãããnewãããåã¯ãå®å
¨åã§ãªããã°ãªããªãããã ããæ½è±¡ã¯ã©ã¹ã¯newã§ããªãããªãã¡ã¬ã³ã¹ã¯ãªãã¸ã§ã¯ãã§ã¯ãªããããnewã§ããªããnewå¼ã®çµæã¯ãåãé
å以å¤ã®å ´åã¯ãçæããããªãã¸ã§ã¯ãã¸ã®ãã¤ã³ã¿ã¼ãè¿ããåãé
åã®å ´åã¯ãé
åã®å
é è¦ç´ ã¸ã®ãã¤ã³ã¿ã¼ãè¿ãã
class C {} ;
int main()
{
// intåã®ãªãã¸ã§ã¯ããçæãã
int * i = new int ;
// Cåã®ãªãã¸ã§ã¯ããçæãã
C * c = new C ;
}
newãããªãã¸ã§ã¯ãã®ããã®ã¹ãã¬ã¼ã¸ã®ç¢ºä¿ã«å¤±æããå ´åãstd::bad_allocä¾å¤ãthrowãããã
int main()
{
try
{
new int ;
}
catch ( std::bad_alloc )
{
// newã失æãã
}
}
詳細ãªã¨ã©ã¼ã«ã¤ãã¦ã¯ãå¾è¿°ããã
newã«ãã£ã¦çæããããªãã¸ã§ã¯ãã¯ãåçã¹ãã¬ã¼ã¸ã®æå¹æéãæã¤ãã¤ã¾ããnewã«ãã£ã¦ä½ããããªãã¸ã§ã¯ããç ´æ£ããããã«ã¯ãæ示çã«deleteã使ããªããã°ãªããªãã
int main()
{
int * ptr = new int ; // çæ
delete ptr ; // ç ´æ£
}
newå¼ã®è©ä¾¡
newå¼ã«ãnewåæååãæå®ããã¦ããå ´åããã®å¼ãè©ä¾¡ããã次ã«ã確ä¿é¢æ°ï¼allocation functionï¼ãå¼ã³åºãã¦ããªãã¸ã§ã¯ãã®çæã«å¿
è¦ãªã¹ãã¬ã¼ã¸ã確ä¿ãããåæåãè¡ãªãã確ä¿ããã¹ãã¬ã¼ã¸ä¸ã«ããªãã¸ã§ã¯ããæ§ç¯ãããããã¦ããªãã¸ã§ã¯ãã¸ã®ãã¤ã³ã¿ã¼ãè¿ãã
é
åã®çæ
newã§é
åãçæããå ´åãè¦ç´ æ°ã¯ãå®æ°ã§ãªãã¦ãæ§ããªãã
void f( int n )
{
// 5åã®intåã®é
åãçæãã
// è¦ç´ æ°ã¯å®æ°
new int[5] ;
// nåã®intåã®é
åãçæãã
// è¦ç´ æ°ã¯å®æ°ã§ã¯ãªã
new int[n] ;
}
é
åã®é
åãã¤ã¾ãå¤æ¬¡å
é
åãçæããå ´åãé
ååã®æåã«æå®ããè¦ç´ æ°ã¯ãå®æ°ã§ãªãã¦ãæ§ããªããæ®ãã®è¦ç´ æ°ã¯ããã¹ã¦å®æ°ã§ãªããã°ãªããªãã
void f( int n )
{
// è¦ç´ æ°ã¯ãã¹ã¦å®æ°
new int[5][5][5] ;
// OK
// æåã®è¦ç´ æ°ã¯å®æ°ã§ã¯ãªã
// æ®ãã¯ãã¹ã¦å®æ°
new int[n][5][5] ;
new int [n] // æåã®è¦ç´ æ°ã¯å®æ°ã§ãªãã¦ããã
[5][5] ; // æ®ãã®è¦ç´ æ°ã¯å®æ°ã§ãªããã°ãªããªã
// ã¨ã©ã¼
// æå以å¤ã®è¦ç´ æ°ãå®æ°ã§ã¯ãªã
new int[n][n][n] ;
new int[5][n][n] ;
new int[5][n][5] ;
}
é
åã®è¦ç´ æ°ã0ã®å ´åãnewã¯ã0åã®é
åãçæãããé
åã®è¦ç´ æ°ãè² æ°ã§ãã£ãå ´åã®æåã¯æªå®ç¾©ã§ããã
int main()
{
// OK
int * ptr = new int[0] ;
// ãã¡ããdeleteããªããã°ãªããªã
delete [] ptr ;
// ã¨ã©ã¼
new int[-1] ;
}
ãããé
ååã®å®æ°ã§ã¯ãªãè¦ç´ æ°ããå®è£
ã®å¶é以ä¸ã®å¤§ããã§ããå ´åãã¹ãã¬ã¼ã¸ã®ç¢ºä¿ã¯å¤±æããããã®å ´åãstd::bad_array_new_lengthä¾å¤ãthrowããããè¦ç´ æ°ãå®æ°ã§ãã£ãå ´åã¯ãé常éããstd::bad_allocä¾å¤ãthrowãããã
// int[n]ã®ã¹ãã¬ã¼ã¸ã確ä¿ã§ããªãã¨ããã
int main()
{
try
{
std::size_t n = std::numeric_limits<std::size_t>::max() ;
new int[n] ; // è¦ç´ æ°ã¯å®æ°ã§ã¯ãªã
}
catch ( std::bad_array_new_length )
{
// ã¹ãã¬ã¼ã¸ã確ä¿ã§ããªãã£ãå ´å
}
try
{
// numeric_limitsã®ã¡ã³ãã¼é¢æ°maxã¯constexpré¢æ°ãªã®ã§ãå®æ°ã«ãªãã
std::size_t const n = std::numeric_limits<std::size_t>::max() ;
new int[n] ; // è¦ç´ æ°ã¯å®æ°
}
catch ( std::bad_alloc )
{
// ã¹ãã¬ã¼ã¸ã確ä¿ã§ããªãã£ãå ´å
}
}
è¦ç´ æ°ãå®æ°ã§ãªãå ´åã§ãã¹ãã¬ã¼ã¸ã確ä¿ã§ããªãå ´åã®ã¿ãstd::bad_array_new_lengthãthrowããããè¦ç´ æ°ãå®æ°ã®å ´åã¯ãé常éããstd::bad_allocãthrowãããã
ãªãã¸ã§ã¯ãã®åæå
çæãããªãã¸ã§ã¯ãã®åæåã¯ãnewåæååã«ãã£ã¦æå®ããããnewåæååã¨ã¯ã( å¼ãªã¹ã )ããåæåãªã¹ãã®ããããã§ãããnewåæååãæå®ãããå ´åããªãã¸ã§ã¯ãã¯ãç´æ¥åæåããããnewåæååãçç¥ãããå ´åãããã©ã«ãåæåãããã
struct C
{
C() {}
C(int) {}
C(int,int) {}
} ;
int main()
{
// newåæååãçç¥ããã¦ãã
// ããã©ã«ãåæå
new C ;
// ç´æ¥åæå
new C(0) ;
new C(0, 0) ;
// åæåãªã¹ã
new C{0} ;
new C{0,0} ;
}
çµã¿è¾¼ã¿åã«å¯¾ããããã©ã«ãåæåã¯ããåæåããªããã¨ããæåãªã®ã§ã注æãè¦ãããåæåã«ã¤ãã¦ã®è©³ãã説æã¯ãåæååãåç
§ã
ååã¨ãã¦ã®auto
newã®ååãautoã®å ´åãnewåæååã¯ã( 代å
¥å¼ )ã®å½¢ãåããªããã°ãªããªãããªãã¸ã§ã¯ãã®åã¯ã代å
¥å¼ã®çµæã®åã¨ãªãããªãã¸ã§ã¯ãã¯ä»£å
¥å¼ã®çµæã®å¤ã§åæåãããã
int f() { return 0 ; }
int main()
{
// intåãå¤ã¯0
new auto( 0 ) ;
// doubleåãå¤ã¯0.0
new auto( 0.0 ) ;
// floatåãå¤ã¯0.0f
new auto( 0.0f ) ;
// intåãå¤ã¯é¢æ°fã®æ»ãå¤
new auto( f() ) ;
}
ããã¯ãautoæå®åã¨ããä¼¼ã¦ããã
placement new
placement newã¨ã¯ã確ä¿é¢æ°ã«è¿½å ã®å¼æ°ã渡ããã¨ãã§ããnewå¼ã®ææ³ã§ãããããã¯ã対å¿ããnewæ¼ç®åã®ãªã¼ãã¼ãã¼ãé¢æ°ãå¼ã³åºãã
void * operator new( std::size_t size, int ) throw(std::bad_alloc)
{ return operator new(size) ; }
void * operator new( std::size_t size, int, int ) throw(std::bad_alloc)
{ return operator new(size) ; }
void * operator new( std::size_t size, int, int, int ) throw(std::bad_alloc)
{ return operator new(size) ; }
int main()
{
new(1) int ; // operator new( sizeof(int), 1 )
new(1,2) int ; // operator new( sizeof(int), 1, 2 )
new(1,2,3) int ; // operator new( sizeof(int), 1, 2, 3 )
}
ãã®ããã«ãnewã¨ååã®éã«ãé常ã®é¢æ°ã®å®å¼æ°ã®ãªã¹ãã®ããã«ã追å ã®å¼æ°ãæå®ãããã¨ãã§ããã追å ã®å¼æ°ã¯ãoperator newã®äºçªç®ä»¥éã®å¼æ°ã«æ¸¡ããããplacement newã®è¿½å ã®å¼æ°ã¯ãã¹ãã¬ã¼ã¸ã確ä¿ããæ¹æ³ã確ä¿é¢æ°ã«æå®ãããªã©ã®ç¨éã«ä½¿ããã
ç¹æ®ãªplacement new
C++ã«ã¯ããããããplacement newãäºã¤å®ç¾©ããã¦ãããoperator new(std::size_t, const std::nothrow_t &) throw()ã¨ãoperator new(std::size_t, void *) throw()ã§ããã
operator new(std::size_t, const std::nothrow_t &) throw()ã¯ãã¹ãã¬ã¼ã¸ã®ç¢ºä¿ã«å¤±æãã¦ãä¾å¤ãæããªãç¹å¥ãªç¢ºä¿é¢æ°ã§ãããããã«ã¯é常ãstd::nothrowã渡ãããã
// ããã©ã«ãã§å®è£
ã«ããå®ç¾©ããã確ä¿é¢æ°
// void * operator new(std::size_t, const std::nothrow_t &) throw() ;
int main()
{
// 失æãã¦ãä¾å¤ãæããªã
int * ptr = new(std::nothrow) int ;
if ( ptr != nullptr )
{
// ãªãã¸ã§ã¯ãã®çæã«æå
// åç
§ã§ãã
*ptr = 0 ;
}
delete ptr ;
}
nothrowçã®newæ¼ç®åã®ãªã¼ãã¼ãã¼ãã¯ãã¹ãã¬ã¼ã¸ã®ç¢ºä¿ã«å¤±æãã¦ããä¾å¤ãæããªãããããã«ãnullãã¤ã³ã¿ã¼ãè¿ããããã¯ãnewã¯ä½¿ãããããã©ããã¦ãä¾å¤ã使ããããªãç¶æ³ã§ä½¿ããã¨ãã§ãããnothrowçã®newãå¼ã³åºããå ´åã¯ãæ»ãå¤ãnullãã¤ã³ã¿ã¼ã§ãããã©ããã確èªããªããã°ãªããªãã
std::nothrow_tã¯ãåã«ãªã¼ãã¼ãã¼ã解決ã®ããã®ã¿ã°ã«éããªããã¾ããå¼æ°ã¨ãã¦æ¸¡ãã¦ããstd::nothrowã¯ãåã«ä¾¿å©ãªå¤æ°ã§ããã
// å®è£
ä¾
namespace std {
struct nothrow_t {} ;
extern const nothrow_t nothrow ;
}
operator new(std::size_t, void *) throw()ã¯ãé常ã«ç¹å¥ãªç¢ºä¿é¢æ°ã§ããããã®å½¢ã®newæ¼ç®åã¯ãªã¼ãã¼ãã¼ãã§ããªãããã®newæ¼ç®åã¯ãã¹ãã¬ã¼ã¸ã確ä¿ãã代ããã«ã第äºå¼æ°ã«æå®ããããã¤ã³ã¿ã¼ã®æãã¹ãã¬ã¼ã¸ä¸ã«ããªãã¸ã§ã¯ããæ§ç¯ããã第äºå¼æ°ã®ãã¤ã³ã¿ã¼ã¯ããªãã¸ã§ã¯ãã®æ§ç¯ã«å¿
è¦ãªãµã¤ãºãã¢ã©ã¤ã¡ã³ãè¦æ±ãªã©ã®æ¡ä»¶ãæºããã¦ããªããã°ãªããªãã
ä¸è¬ã«ãplacement newã¨ããã°ããã®ç¹å¥ãªnewæ¼ç®åã®å¼ã³åºããæå³ããããã ããæ£å¼ãªplacement newã¨ããç¨èªã®æå³ã¯ã追å ã®å®å¼æ°ãæå®ããnewå¼ã®ææ³ã§ããã
struct C
{
C(){ std::cout << "constructed." << std::endl ; }
~C(){ std::cout << "destructed." << std::endl ; }
} ;
int main()
{
// ã¹ãã¬ã¼ã¸ãèªåã§ç¢ºä¿ãã
// operator newã®è¿ãã¹ãã¬ã¼ã¸ã¯ãããããã¢ã©ã¤ã¡ã³ãè¦æ±ãæºãã
void * storage = operator new( sizeof(C) ) ;
// placement newã«ãã£ã¦ãã¹ãã¬ã¼ã¸ä¸ã«ãªãã¸ã§ã¯ããæ§ç¯
C * ptr = new( storage ) C ;
// ã¹ãã¬ã¼ã¸ã®è§£æ¾ã®åã«ããã¹ãã©ã¯ã¿ã¼ãå¼ã³åºã
ptr->~C() ;
// ã¹ãã¬ã¼ã¸ãèªåã§è§£æ¾ãã
operator delete( storage ) ;
}
ã¹ãã¬ã¼ã¸ã¯èªåã§ç¢ºä¿ããªããã°ãªããªãã®ã§ãé常éãdeleteå¼ã使ããã¨ã¯ã§ããªãããã¹ãã©ã¯ã¿ã¼ãèªåã§å¼ã³åºãããã®å¾ã«ãã¹ãã¬ã¼ã¸ãèªåã§è§£æ¾ããªããã°ãªããªãã
ã¹ãã¬ã¼ã¸ã¯ãåçã¹ãã¬ã¼ã¸ã§ãªãã¦ãæ§ããªãããã ããã¢ã©ã¤ã¡ã³ãè¦æ±ã«ã¯æ³¨æããªããã°ãªããªãã
struct C
{
int x ;
double y ;
} ;
int main()
{
// ã¹ãã¬ã¼ã¸ã¯èªåå¤æ°
char storage [[align(C)]] [sizeof(C)] ;
// placement newã«ãã£ã¦ãã¹ãã¬ã¼ã¸ä¸ã«ãªãã¸ã§ã¯ããæ§ç¯
C * ptr = new( storage ) C ;
// ãã¹ãã©ã¯ã¿ã¼ã¯trivialãªã®ã§å¼ã¶å¿
è¦ã¯ãªãã
// ã¹ãã¬ã¼ã¸ã¯èªåå¤æ°ãªã®ã§ã解æ¾ããå¿
è¦ã¯ãªã
}
ãã®ä¾ã§ã¯ãsizeof(C)ã®å¤§ããã®charé
åã®ä¸ã«ãªãã¸ã§ã¯ããæ§ç¯ãã¦ãããã¢ããªãã¥ã¼ãã使ããã¢ã©ã¤ã¡ã³ããæå®ãã¦ãããã¨ã«æ³¨æã
ãã®placement newã¯ãSTLã®ã¢ãã±ã¼ã¿ã¼ãå®è£
ããã®ã«ã使ããã¦ããã
ã¹ãã¬ã¼ã¸ã®ç¢ºä¿ã«å¤±æããå ´åã®ã¨ã©ã¼å¦ç
確ä¿é¢æ°ãã¹ãã¬ã¼ã¸ã®ç¢ºä¿ã«å¤±æããå ´åãstd::bad_allocä¾å¤ãthrowããããplacement newã®std::nothrow_tãå¼æ°ã«åã確ä¿é¢æ°ã®å ´åã¯ãæ»ãå¤ã®ãã¤ã³ã¿ã¼ããnullãã¤ã³ã¿ã¼ã¨ãªãã
int main()
{
try
{
new int ;
}
catch ( std::bad_alloc )
{
// ã¨ã©ã¼å¦ç
}
int * ptr = new(std::nothrow) int ;
if ( ptr == nullptr )
{
// ã¨ã©ã¼å¦ç
}
}
åæåã«å¤±æããå ´åã®ã¨ã©ã¼å¦ç
newã失æããå ´åã¯ãäºã¤ãããã¹ãã¬ã¼ã¸ã確ä¿ã«å¤±æããå ´åã¨ããªãã¸ã§ã¯ãã®åæåã«å¤±æããå ´åã§ããã
ãã¨ãã¹ãã¬ã¼ã¸ã確ä¿ã§ããã¨ãã¦ãããªãã¸ã§ã¯ãã®åæåã¯ã失æããå¯è½æ§ãããããªããªãã°ãåæåã®éã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãä¾å¤ãæãããããããªãããã ã
// ä¾å¤ãæããã³ã³ã¹ãã©ã¯ã¿ã¼ãæã¤ã¯ã©ã¹
struct Fail
{
Fail() { throw 0 ; }
} ;
int main()
{
try
{
new Fail ; // å¿
ãåæåã«å¤±æãã
}
catch ( int ) { }
}
ã³ã³ã¹ãã©ã¯ã¿ã¼ãä¾å¤ãæããå ´åãnewã¯ã確ä¿ããã¹ãã¬ã¼ã¸ãã対å¿ãã解æ¾é¢æ°ï¼deallocation functionï¼ãå¼ã³åºãã¦è§£æ¾ãããããã¦ãã³ã³ã¹ãã©ã¯ã¿ã¼ã®æããä¾å¤ãããã®ã¾ã¾å¤ã«ä¼ããã
対å¿ãã解æ¾é¢æ°ã¨ã¯ä½ããé常ã¯ãoperator delete(void *)ã§ãããããããplacement newã使ã£ã¦ããå ´åã¯ãæåã®å¼æ°ãé¤ããæ®ãã®å¼æ°ã®æ°ã¨åãä¸è´ããoperator deleteã«ãªãã
// placement new
void * operator new( std::size_t size, int, int, int ) throw(std::bad_alloc)
{ return operator new(size) ; }
// placement delete
void operator delete( void * ptr, int, int, int ) throw()
{
std::cout << "placement delete" << std::endl ;
operator delete(ptr) ;
}
// ä¾å¤ãæãããããããªãã¯ã©ã¹
struct Fail
{
Fail() noexcept(false) ; // ä¾å¤ãæããå¯è½æ§ããã
} ;
int main()
{
// ã³ã³ã¹ãã©ã¯ã¿ã¼ãä¾å¤ãæããå ´åã
// operator delete( /*ã¹ãã¬ã¼ã¸ã¸ã®ãã¤ã³ã¿ã¼*/, 1, 2, 3 )ãå¼ã°ãã
Fail * ptr = new(1, 2, 3) Fail ;
// operator delete(void *)ãå¼ã°ãã
delete ptr ;
}
åæåã失æããå ´åã®placement deleteã®å¼ã³åºãã«ã¯ãplacement newã«æ¸¡ããã追å ã®å¼æ°ã¨ãå
¨ãåãå¤ã渡ãããã
ãªããdeleteå¼ã¯é常éããoperator delete(void *)ãå¼ã³åºãããã¨ãplacement newã§ç¢ºä¿ãããªãã¸ã§ã¯ãã§ãã£ã¦ããdeleteå¼ã§ã¯å¯¾å¿ãã解æ¾é¢æ°ã¯å¼ã°ããªããããã¾ã§ãåæåã®éã«å¼ã°ããã ãã§ãããã¾ããdeleteå¼ãããplacement deleteãå¼ã³åºãææ³ãåå¨ããªããããã¯ããnewã®éã«æå®ããæ
å ±ããdeleteã®éã«ã¾ã§ä¿æãã¦ããã®ã¯ãã¦ã¼ã¶ã¼å´ã«ã¨ã£ã¦ãå®è£
å´ã«ã¨ã£ã¦ãå°é£ã§ãããã¨ããææ³ã«åºã¥ãã
確ä¿é¢æ°ã®é¸æ
newå¼ãå¼ã³åºã確ä¿é¢æ°ã¯ã以ä¸ã®æ¹æ³ã§é¸æãããã
çæããã¯ã©ã¹ã®ã¡ã³ãã¼é¢æ°ã«ãoperator newã®ãªã¼ãã¼ãã¼ããããå ´åãã¡ã³ãã¼é¢æ°ãé¸ã°ãããã¡ã³ãã¼é¢æ°ã«ãã£ã¦ãªã¼ãã¼ãã¼ãããã¦ããªãå ´åãã°ãã¼ãã«ã¹ã³ã¼ãã®operator newãé¸ã°ãããnewå¼ããã::newãã§å§ã¾ãå ´åããã¨ãã¡ã³ãã¼é¢æ°ã«ãããªã¼ãã¼ãã¼ãããã£ã¦ããã°ãã¼ãã«ã¹ã³ã¼ãã®operator newãé¸ã°ããã
// ãªã¼ãã¼ãã¼ããã
struct A
{
void * operator new( std::size_t size ) throw(std::bad_alloc) ;
} ;
// ãªã¼ãã¼ãã¼ããªã
struct B { } ;
int main()
{
// A::operator newãé¸ã°ãã
new A ;
// ::operator newãé¸ã°ãã
new B ;
// ::operator newãé¸ã°ãã
::new A ;
}
é
åã®å ´åãåæ§ã§ãããé
åã®å ´åã¡ã³ãã¼é¢æ°ã¯ãé
åã®è¦ç´ ã®ã¯ã©ã¹åã®ã¡ã³ãã¼ããæ¢ãããã
// ãªã¼ãã¼ãã¼ããã
struct A
{
void * operator new[]( std::size_t size ) throw(std::bad_alloc) ;
} ;
// ãªã¼ãã¼ãã¼ããªã
struct B { } ;
int main()
{
// A::operator new[]ãé¸ã°ãã
new A[1] ;
// ::operator new[]ãé¸ã°ãã
new B1[1] ;
// ::operator new[]ãé¸ã°ãã
::new A[1] ;
}
placement newã®å ´åã追å ã®å¼æ°ãããªã¼ãã¼ãã¼ã解決ã«ãã£ã¦èæ
®ãããæãæé©ãªãªã¼ãã¼ãã¼ãé¢æ°ãé¸ã°ããã
void * operator new( std::size_t size, int ) throw( std::bad_alloc ) ;
void * operator new( std::size_t size, double ) throw( std::bad_alloc ) ;
void * operator new( std::size_t size, int, int ) throw( std::bad_alloc ) ;
int main()
{
// operator new( std::size_t size, int )
new(0) int ;
// operator new( std::size_t size, double )
new(0.0) int ;
// operator new( std::size_t size, int, int )
new(1, 2) int ;
}
CV修飾ããã¦ããåã®new
CV修飾åã®ããåãnewã§ãããç¹ã«å¤ãããã¨ã¯ãªãã
int main()
{
int const * ptr = new int const(0) ;
delete ptr ;
}
確ä¿é¢æ°ã¨è§£æ¾é¢æ°ã®å
·ä½çãªå®è£
æ¹æ³ã«ã¤ãã¦ã¯ãåçã¡ã¢ãªã¼ç®¡çãåç
§ã
::opt delete å¼
::opt delete [ ] å¼
newå¼ã«ãã£ã¦ç¢ºä¿ãããªãã¸ã§ã¯ãã®å¯¿å½ã¯ãã¹ã³ã¼ãã«ã¯ã¨ããããªãããªãã¸ã§ã¯ããç ´æ£ããããã°ãdeleteå¼ã§è§£æ¾ããªããã°ãªããªãã
deleteã®ãªãã©ã³ãã®å¤ã¯ãnewå¼ã«ãã£ã¦è¿ããããã¤ã³ã¿ã¼ã§ãªããã°ãªããªãããªãã¸ã§ã¯ããé
åã§ã¯ãªãå ´åã¯ãdeleteããé
åã®å ´åã¯ãdelete [ ]ã使ããdeleteå¼ã®çµæã®åã¯ãvoidã§ããã
int main()
{
int * ptr = new int ;
int * array_ptr = new int[1] ;
delete ptr ;
delete[] array_ptr ;
}
é
åã§ãããã©ããã§ãdeleteã¨delete[]ã使ãåããªããã°ãªããªããããã¯ééããããã®ã§æ³¨æãããã¨ã
deleteã®ãªãã©ã³ããã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã§ãã£ãå ´åãéexplicitãªã¦ã¼ã¶ã¼å®ç¾©ã®å¤æãå®ç¾©ããã¦ããå ´åããªãã¸ã§ã¯ãã¸ã®ãã¤ã³ã¿ã¼ã«å¤æãããã
struct C
{
operator int *() { return new int ; }
} ;
int main()
{
C c ;
// C::operator int *()ãå¼ã³åºãã
// æ»ãå¤ã解æ¾ããã
delete c ;
}
deleteå¼ã¯ãã¾ãããã¤ã³ã¿ã¼ã®æã示ããªãã¸ã§ã¯ãã®ãã¹ãã©ã¯ã¿ã¼ãå¼ã³åºãã次ã«ã解æ¾é¢æ°ãå¼ã³åºãã¦ãã¹ãã¬ã¼ã¸ã解æ¾ããããªãã¸ã§ã¯ãã®æãåããã¡ã³ãã¼é¢æ°ã¨ãã¦operator deleteã®ãªã¼ãã¼ãã¼ããæã¤å ´åãã¡ã³ãã¼é¢æ°ãå¼ã°ããããªã¼ãã¼ãã¼ããããã¡ã³ãã¼é¢æ°ãåå¨ããªãå ´åãã°ãã¼ãã«ã¹ã³ã¼ãã®operator deleteãå¼ã³åºããdeleteå¼ããã::deleteãã§å§ã¾ãå ´åãã¡ã³ãã¼é¢æ°ã®ãªã¼ãã¼ãã¼ãã®æç¡ã«ããããããã°ãã¼ãã«ã¹ã³ã¼ãã®operator deleteãå¼ã³åºãã
// ãªã¼ãã¼ãã¼ããã
struct A
{
void operator delete( void * ) throw() ;
} ;
// ãªã¼ãã¼ãã¼ããªã
struct B { } ;
int main()
{
A * a = new A ;
// A::operator delete(void*)ãå¼ã³åºã
delete a ;
B * b = new B ;
// ::operator delete(void*)ãå¼ã³åºã
delete b ;
a = new A ;
// ::operator delete(void*)ãå¼ã³åºã
::delete a ;
}
ãªãã¸ã§ã¯ãããplacement newã§ç¢ºä¿ãããã¨ãã¦ããå¼ã³åºã解æ¾é¢æ°ã¯ãå¿
ãoperator delete(void *)ããããã¯operator delete[](void *)ã¨ãªããdeleteå¼ã§ã¯ãplacement deleteã¯å¼ã³åºãããªããã¾ããdeleteå¼ã«ã¯ãplacement deleteãå¼ã³åºãããã®ææ³ãåå¨ããªããã©ããã¦ãplacement deleteãå¼ã³åºãããå ´åã¯ãæåã§ãã¹ãã©ã¯ã¿ã¼ãå¼ã³åºããããã«æåã§placement deleteãå¼ã³åºããããªãã
// placement delete
void operator delete( void *, int ) throw() ;
struct C
{
C() {}
~C(){}
} ;
void f()
{
C * ptr = new C ;
// ããã§ã¯ãoperator delete( void * )ãå¼ã³åºããã
delete ptr ;
// çä¼¼ãã¹ãã©ã¯ã¿ã¼å¼ã³åºã
ptr->~C() ;
// operator deleteã®æ示çãªå¼ã³åºã
operator delete( ptr, 0 ) ;
}
alignof ( åå )
alignofå¼ã¯ããªãã©ã³ãã®åã®ã¢ã©ã¤ã¡ã³ãè¦æ±ãè¿ãããªãã©ã³ãã®åã¯ãå®å
¨ãªãªãã¸ã§ã¯ãåãããã®é
åãããã¯ãªãã¡ã¬ã³ã¹ã§ãªããã°ãªããªããå¼ã®çµæã¯ãstd::size_tåã®å®æ°ã«ãªãã
ãªãã©ã³ããããªãã¡ã¬ã³ã¹åã®å ´åãçµæã¯åç
§ãããåã®ã¢ã©ã¤ã¡ã³ãè¦æ±ã«ãªããé
åã®å ´åãçµæã¯é
åã®è¦ç´ ã®åã®ã¢ã©ã¤ã¡ã³ãè¦æ±ã«ãªãã
struct C
{
char c ; int i ; double d ;
} ;
void f()
{
// charåã®ã¢ã©ã¤ã¡ã³ãè¦æ±ãè¿ã
alignof( char ) ;
// intåã®ã¢ã©ã¤ã¡ã³ãè¦æ±ãè¿ã
alignof( int ) ;
// doubleåã®ã¢ã©ã¤ã¡ã³ãè¦æ±ãè¿ã
alignof( double ) ;
// Cåã®ã¢ã©ã¤ã¡ã³ãè¦æ±ãè¿ã
alignof( C ) ;
}
noexcept ( æªè©ä¾¡å¼ )
noexceptæ¼ç®åã¯ããªãã©ã³ãã®å¼ããä¾å¤ãæããå¯è½æ§ã®ããå¼ãå«ããã©ãããè¿ããnoexceptæ¼ç®åã®çµæã®åã¯boolã®å®æ°ã§ãä¾å¤ãæããå¯è½æ§ã®ããå¼ãå«ã¾ãªãå ´åtrueããå«ãå ´åfalseãè¿ãããªãã©ã³ãã®å¼ã¯ãè©ä¾¡ãããªãã
çµæãfalseã¨ãªãå ´åãããªãã¡ãä¾å¤ãæããå¯è½æ§ã®ããå¼ã¨ã¯ã以ä¸ã®éãã§ããã
throwå¼ã
// false
noexcept( throw 0 ) ;
dynamic_castå¼ãdynamic_cast<T>(v)ã«ããã¦ãTããªãã¡ã¬ã³ã¹åã§ãå®è¡æãã§ãã¯ãå¿
è¦ãªå ´åã
struct Base { virtual void f() {} } ;
struct Derived : Base { } ;
void f( Base & ref )
{
// false
noexcept( dynamic_cast<Derived & >( ref ) ) ;
}
typeidå¼ã«ããã¦ããªãã©ã³ããglvalueã§ãå®è¡æãã§ãã¯ãå¿
è¦ãªå ´åã
struct Base { virtual void f() {} } ;
struct Derived : Base { } ;
void f( Base * ptr )
{
// false
noexcept( typeid( *ptr ) ) ;
}
é¢æ°ãã¡ã³ãã¼é¢æ°ãé¢æ°ãã¤ã³ã¿ã¼ãã¡ã³ãã¼é¢æ°ãã¤ã³ã¿ã¼ãå¼ã³åºãå¼ã«ããã¦ãå¼ã³åºãé¢æ°ã®ä¾å¤æå®ããç¡ä¾å¤ï¼non-throwingï¼ã§ãªããã®ã
void a() ;
void b() noexcept ; // non-throwing
void c() noexcept(true) ; // non-throwing
void d() noexcept(false) ;
void e() throw() ; // non-throwing
void f() throw(int) ;
int main()
{
noexcept( a() ) ; // false
noexcept( b() ) ; // true
noexcept( c() ) ; // true
noexcept( d() ) ; // false
noexcept( e() ) ; // true
noexcept( f() ) ; // false
}
é¢æ°ãããå¼ã³åºãå¼ãã¨ããã®ã¯ãé¢æ°ãéæ¥çã«å¼ã³åºãå ´åã該å½ããããã¨ãã°ãnewå¼ã¯ç¢ºä¿é¢æ°ãå¼ã³åºãã®ã§ãé¢æ°ãå¼ã³åºãå¼ã§ããããã®å ´åã®çµæã¯ãå¼ã³åºããã確ä¿é¢æ°ã®ä¾å¤æå®ã«ä¾åããã
int main()
{
// ::operator new( std::size_t ) throw( std::bad_alloc) ãå¼ã³åºã
std::cout << noexcept( new int ) ; // false
// ::operator new( std::size_t, std::nothrow_t ) throw() ãå¼ã³åºã
std::cout << noexcept( new(std::nothrow) int ) ; // true
}
ãã¡ãããæ¼ç®åã®ãªã¼ãã¼ãã¼ãé¢æ°ãããé¢æ°ãã§ãããå¾ã£ã¦ãæ¼ç®åã®ãªã¼ãã¼ãã¼ãé¢æ°ãå¼ã³åºãå¼ã¯ãé¢æ°ãå¼ã³åºãå¼ã§ããã
struct C
{
C operator +( C ) ;
C operator -( C ) noexcept ;
} ;
int main()
{
int i = 0 ;
noexcept( i + i ) ; // true
C c ;
noexcept( c + c ) ; // false
noexcept( c - c ) ; // true
}
ãã®ä»ã«ããé¢æ°ãéæ¥çã«å¼ã³åºãå¯è½æ§ã®ããå¼ã¨ããã®ã¯ãé常ã«å¤ãã®ã§ã注æããªããã°ãªããªãã
é¢æ°ã®ãªã¼ãã¼ãã¼ã解決ã¯éçã«è¡ãããã®ã§ãå½ç¶ãå¼ã³åºãããé¢æ°ã«å¿ãã¦çµæãå¤ããã
void f(int) noexcept ;
void f(double) ;
int main()
{
noexcept( f(0) ) ; // true
noexcept( f(0.0) ) ; // false
}
ä¾å¤ãæããå¯è½æ§ã®ããå¼ããå«ããã¨ããã®ã¯ããã¨ããã®å¼ã絶対ã«è©ä¾¡ãããªãã§ããä¾å¤ãæããå¯è½æ§ãããã¨ã¿ãªããããä¾ãã°ã
noexcept( true ? 0 : throw 0 ) ; // false
ãã®noexceptã®ãªãã©ã³ãã®å¼ã¯ãããè©ä¾¡ãããå ´åã決ãã¦ä¾å¤ãæãããã¨ããªããããããä¾å¤ãæããå¯è½æ§ã®ããå¼ãå«ãã§ããã®ã§ãnoexceptã®çµæã¯falseã¨ãªãã
ä¸è¨ä»¥å¤ã®å ´åãnoexceptã®çµæã¯trueã¨ãªãã
struct Base { } ;
struct Derived : Base { } ;
int main()
{
noexcept( 0 ) ; // true
Derived d ;
noexcept( d ) ; // true
noexcept( dynamic_cast<Base &>( d ) ) ; // true
noexcept( typeid( d ) ) ; // true
}
注æï¼Cå½¢å¼ã®ãã£ã¹ãã«ã¯æ§ã
ãªåé¡ãããã®ã§ã使ã£ã¦ã¯ãªããªãã
( åå ) å¼
ããã¯ãæªåé«ãCå½¢å¼ã®ãã£ã¹ãã§ããã
int main()
{
int i = 0 ;
double * ptr = (double *) &i ;
}
Cå½¢å¼ã®ãã£ã¹ãã¯ãstatic_castã¨reinterpret_castã¨const_castãçµã¿åãããåãããããçµã¿åããã¯ã以ä¸ã®é åºã§æ±ºå®ãããã
- const_cast
- static_cast
- static_castã¨const_cast
- reinterpret_cast
- reinterpret_castã¨const_cast
ä¸ããä¸ã«è©ä¾¡ãã¦ãããå¤æã§ããçµã¿åãããè¦ã¤ãã£ãã¨ããã§ããã®ãã£ã¹ãã使ã£ã¦å¤æããã
ãã ããCå½¢å¼ã®ãã£ã¹ãã§ã¯ãstatic_castã«ç¹å¥ãªå¤æ´ãä¸ã¤å ãããã¯ã©ã¹ã®ã¢ã¯ã»ã¹æå®ãç¡è¦ã§ããæ©è½ã§ããã
æ´¾çã¯ã©ã¹ã¸ã®ãã¤ã³ã¿ã¼ããªãã¡ã¬ã³ã¹ãããåºæ¬ã¯ã©ã¹ã¸ã®ãã¤ã³ã¿ã¼ããªãã¡ã¬ã³ã¹ã«å¤æã§ãããæåéãå¤æã§ãããã¢ã¯ã»ã¹æå®ãªã©ã¯èæ
®ãããªãã
struct Base { } ;
struct Derived : private Base { } ;
int main()
{
Derived d ;
Base & ref1 = (Base &) d ; // OK
Base & ref2 = static_cast<Base &>(d) ; // ill-formed
}
ãã®ãããpublicã§ã¯ãªãåºæ¬ã¯ã©ã¹ã«ã¢ã¯ã»ã¹ã§ãã¦ãã¾ãã
æ´¾çã¯ã©ã¹ã®ã¡ã³ãã¼ã¸ã®ãã¤ã³ã¿ã¼ãããææ§ã§ã¯ãªãévirtualãªåºæ¬ã¯ã©ã¹ã®ã¡ã³ãã¼ã¸ã®ãã¤ã³ã¿ã¼ã«å¤æã§ãããæåéãå¤æã§ãããã¢ã¯ã»ã¹æå®ãªã©ã¯èæ
®ãããªãã
struct Base { } ;
struct Derived : private Base { int x ; } ;
int main()
{
int Base::* ptr1 = (int Base::*) &Derived::x ; // OK
int Base::* ptr2 = static_cast<int Base::*>(&Derived::x) ; // ill-formed
}
ããããã¢ã¯ã»ã¹æå®ãç¡è¦ã§ãã¦ãã¾ãã
ææ§ã§ã¯ãªãévirtualãªåºæ¬ã¯ã©ã¹ã®ãã¤ã³ã¿ã¼ããªãã¡ã¬ã³ã¹ãããã¯ã¡ã³ãã¼ã¸ã®ãã¤ã³ã¿ã¼ã¯ãæ´¾çã¯ã©ã¹ã®ãã¤ã³ã¿ã¼ããªãã¡ã¬ã³ã¹ãããã¯ã¡ã³ãã¼ã¸ã®ãã¤ã³ã¿ã¼ã«å¤æã§ãããæåéãå¤æã§ãããã¢ã¯ã»ã¹æå®ãªã©ã¯èæ
®ãããªãã
struct Base { int x ; } ;
struct Derived : private Base { } ;
int main()
{
Derived d ;
d.x = 0 ; // ill-formed. ã¢ã¯ã»ã¹æå®ã®ãã
int Derived::* ptr = (int Derived::*) &Base::x ; // well-formed.
d.*ptr = 0 ; // well-formed. Cå½¢å¼ã®ãã£ã¹ãã使ã£ããããã¢ã¯ã»ã¹æå®ãç¡è¦ã§ãã¦ãã
}
Cå½¢å¼ã®ãã£ã¹ãã§ããã§ããªããã£ã¹ãã¨ã¯ãã¯ã©ã¹ã®ã¢ã¯ã»ã¹æå®ãç¡è¦ãããããã¯ã©ã¹é層ã®ããã²ã¼ã·ã§ã³ãè¡ããã£ã¹ãã®ãã¨ã§ããã
ãããã®ãã£ã¹ãã¯ãreinterpret_castã§ãã§ããããã ããreinterpret_castã¯ãã¯ã©ã¹é層ã®ããã²ã¼ã·ã§ã³ãè¡ããªãã®ã§ãæ£ããåããªããstatic_castã¯ãã¯ã©ã¹é層ã®ããã²ã¼ã·ã§ã³ãè¡ãã®ã§ãæ£ããåãã
ã¢ã¯ã»ã¹æå®ãç¡è¦ã§ãããã£ã¹ããããªããã°ãªããªãå ´åã¨ããã®ã¯ãç¾å®ã«ã¯åå¨ããªãã¯ãã§ãããã¢ã¯ã»ã¹æå®ãç¡è¦ããããããªãã°ãæåããpublicã«ãã¦ããã°ããã
reinterpret_castã¯å¿
è¦ã§ãããC++ãå¿
è¦ã¨ãããç°å¢ã§ã¯ããã¤ã³ã¿ã¼ã®å
é¨çãªå¤ãããã®ã¾ã¾å¥ã®åã®ãã¤ã³ã¿ã¼ã¨ãã¦ä½¿ããªããã°ãªããªãå ´åãåå¨ãããã¾ããæ¢åã®Cã®ã³ã¼ãã¨ã®äºææ§ã®ãããconst_castãæ®å¿µãªããå¿
è¦ã§ãããããããã¢ã¯ã»ã¹æå®ã¯ãC++ã«æ°ãã追å ãããæ¦å¿µã§ããã®ã§ãäºææ§ã®åé¡ãåå¨ããªãããã¾ããã¢ã¯ã»ã¹æå®ãç¡è¦ããªããã°ãªããªãå ´åã¨ããã®ããå
¨ãèããããªããå¾ã£ã¦ãã¢ã¯ã»ã¹æå®ãç¡è¦ã§ããã¨ããçç±ã§ãCå½¢å¼ã®ãã£ã¹ãã使ã£ã¦ã¯ãªããªãã
ãããããCå½¢å¼ã®ãã£ã¹ãã¯æ ¹æ¬çã«éªæªã§ããã®ã§ã使ã£ã¦ã¯ãªããªããCå½¢å¼ã®ãã£ã¹ãã®åé¡ç¹ã¯ãã§ãããã¨ãå¤ãããã¨ãããã¨ã ãå®å
¨ãªãã£ã¹ãããå±éºãªãã£ã¹ãããå
¨ãåãææ³ã§è¡ããã¨ãã§ãããC++ã§ã¯ããã®åé¡ã解決ããããã«ããã£ã¹ããä¸ã¤ã«åãããstatic_castãreinterpret_castãconst_castã§ãããC++ã§ã¯ããã®æ°ããå½¢å¼ã®ãã£ã¹ãã使ãã¹ãã§ããã以ä¸ã«ãã®æ¦è¦ã¨ç°¡åãªä½¿ãåããã¾ã¨ããã
static_castã¯ãã»ã¨ãã©ãå®å
¨ãªãã£ã¹ãã§ãããstatic_castã¯ãåå¤æãå®å
¨ã«ãããããå¤ãå¤ãããã¨ããããå¤ãå¤æ´ããã®ã§ãstatic_castã¯ãã¯ã©ã¹é層ã®ããã²ã¼ã·ã§ã³ãè¡ããã¨ãã§ãããæ´¾çã¯ã©ã¹ã¨åºæ¬ã¯ã©ã¹ã¨ã®éã®ãã¤ã³ã¿ã¼ã®åå¤æã¯ããã¤ã³ã¿ã¼ã®å
é¨çãªå¤ãå¤ããå¯è½æ§ãããããã ããã¤ã³ã¿ã¼ã®å¤ã¯ããã¨ããå®è£
ä¾åã§ããããæãå¤ãã®ç°å¢ã§åç¾ã§ããã³ã¼ãã¯ãè¤æ°ã®åºæ¬ã¯ã©ã¹ã使ããã®ã ã
struct Base1 { int x ; } ;
struct Base2 { int x ; } ;
struct Derived : Base1, Base2 { } ;
int main()
{
Derived d ;
Derived * ptr = &d ;
// åºæ¬ã¯ã©ã¹ã¸ã®ãã£ã¹ã
Base1 * base1 = static_cast<Base1 *>( ptr ) ;
Base2 * base2 = static_cast<Base2 *>( ptr ) ;
// æ´¾çã¯ã©ã¹ã¸ã®ãã£ã¹ã
Derived * d1 = static_cast<Derived *>( base1 ) ;
Derived * d2 = static_cast<Derived *>( base2 ) ;
// æ´¾çã¯ã©ã¹ã®ãã¤ã³ã¿ã¼ã®å¤
std::printf( "Derived *: %p\n", ptr ) ;
// åºæ¬ã¯ã©ã¹ã®ãã¤ã³ã¿ã¼ã®å¤ã¯åããï¼
std::printf( "Base1 *: %p\n", base1 ) ;
std::printf( "Base2 *: %p\n", base2 ) ;
// æ´¾çã¯ã©ã¹ã«æ»ããå ´åã¯ã©ããï¼
std::printf( "from Base1 * to Derived *: %p\n", d1 ) ;
std::printf( "from Base1 * to Derived *: %p\n", d2 ) ;
}
è¤æ°ã®åºæ¬ã¯ã©ã¹ã®å ´åãåºæ¬ã¯ã©ã¹ã®ãµããªãã¸ã§ã¯ããè¤æ°ããã®ã§ãæ´¾çã¯ã©ã¹ã¨åºæ¬ã¯ã©ã¹ã®ãã¤ã³ã¿ã¼ã®éã§ãåãå¤ã使ããã¨ãã§ããªããå¾ã£ã¦ãåºæ¬ã¯ã©ã¹ã¸ã®ãã¤ã³ã¿ã¼ã«ãã£ã¹ãããã«ã¯ãã¹ãã¬ã¼ã¸ä¸ã®ããã®åºæ¬ã¯ã©ã¹ã®ãµããªãã¸ã§ã¯ããæããã¤ã³ã¿ã¼ãè¿ããªããã°ãªããªããã¾ããæ´¾çã¯ã©ã¹ã¸ã®ãã¤ã³ã¿ã¼ã«ãã£ã¹ãããã«ã¯ãå¤ãæ»ããªããã°ãªããªãã
ãã®ãããã¯ã©ã¹é層ã®ããã²ã¼ã·ã§ã³ã«ã¯ãstatic_castãdynamic_castãç¨ããªããã°ãªããªãã
reinterpret_castã¯ãå±éºã§æç´ãªãã£ã¹ãã§ãããreinterpret_castã¯ãå¤ãå¤ããªãããã ããã®å¤ã®åã ããå¤æ´ãããreinterpret_castã¯ãã¯ã©ã¹é層ã®ããã²ã¼ã·ã§ã³ãã§ããªãã
const_castã¯ãCV修飾åãå¤ããã£ã¹ãã§ããã
ãããã©ã®ãã£ã¹ãã使ãã¹ããªã®ãå¤æã§ããªãå ´åã¯ãã¾ãstatic_castã使ã£ã¦ããã°åé¡ã¯ãªãããããstatic_castã失æããå ´åãæ¬å½ã«ãã®ãã£ã¹ãã¯å®å
¨ãªã®ãã¨ãããã¨ã確ããã¦ãããreinterpret_castã使ãã¹ãã§ãããconst_castã¯ãæ¢åã®Cã®ã³ã¼ãã®å©ç¨ä»¥å¤ã«ä½¿ã£ã¦ã¯ãªããªãã
å¼ .* å¼
å¼ ->* å¼
ã¡ã³ãã¼ã¸ã®ãã¤ã³ã¿ã¼æ¼ç®åã¯ããå·¦ããå³ãã«è©ä¾¡ãããã
ã¡ã³ãã¼ã¸ã®ãã¤ã³ã¿ã¼æ¼ç®åã¯ãã¯ã©ã¹ã®ã¡ã³ãã¼ã¸ã®ãã¤ã³ã¿ã¼ã使ã£ã¦ãã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã®ã¡ã³ãã¼ã«ã¢ã¯ã»ã¹ããããã®æ¼ç®åã§ãããã¯ã©ã¹ã®ã¡ã³ãã¼ã¸ã®ãã¤ã³ã¿ã¼ãåç
§ããããã«ã¯ãåç
§ããã¯ã©ã¹ã®ãªãã¸ã§ã¯ããå¿
è¦ã§ããã
.*æ¼ç®åã®ç¬¬ä¸ãªãã©ã³ãã«ã¯ãã¯ã©ã¹ã®ãªãã¸ã§ã¯ããæå®ããã->*æ¼ç®åã®ç¬¬ä¸ãªãã©ã³ãã«ã¯ãã¯ã©ã¹ã¸ã®ãã¤ã³ã¿ã¼ãæå®ããã第äºãªãã©ã³ãã«ã¯ãã¯ã©ã¹ã®ã¡ã³ãã¼ã¸ã®ãã¤ã³ã¿ã¼ãæå®ããã
struct C
{
int member ;
} ;
int main()
{
int C::* mem_ptr = &C::member ;
C c ;
c.*mem_ptr = 0 ;
C * ptr = &c ;
ptr->*mem_ptr = 0 ;
}
ã¡ã³ãã¼é¢æ°ã®å¼ã³åºãã®éã¯ãæ¼ç®åã®åªå
é ä½ã«æ°ãã¤ããªããã°ãªããªãã
struct C
{
void member() {}
} ;
int main()
{
void (C::* mem_ptr)() = &C::member ;
C c ;
(c.*mem_ptr)() ;
C * ptr = &c ;
(ptr->*mem_ptr)() ;
}
ãªããªãã°ãã¡ã³ãã¼ã¸ã®ãã¤ã³ã¿ã¼æ¼ç®åã®å¼ãããé¢æ°å¼ã³åºãå¼ã®åªå
é ä½ã®æ¹ãé«ãã®ã§ãc.*mem_ptr()ã¨ããå¼ã¯ãc.*( mem_ptr() )ã¨ããå¼ã«è§£éããã¦ãã¾ããããã¯ãmem_ptrã¨ããååã«å¯¾ãã¦ãé¢æ°å¼ã³åºãå¼ãé©ç¨ããå¾ããã®çµæããã¯ã©ã¹ã®ã¡ã³ãã¼ã¸ã®ãã¤ã³ã¿ã¼ã¨ãã¦ä½¿ãå¼ã§ããããã®ããã«è§£éããããã¨ãé¿ããããã«ãæ¬å¼§å¼ã使ããªããã°ãªããªãã
ãã®ä»ã®ç´°ããã«ã¼ã«ã«ã¤ãã¦ã¯ãã¯ã©ã¹ã¡ã³ãã¼ã¢ã¯ã»ã¹ã¨åãã§ããã
å¼ * å¼
å¼ / å¼
å¼ % å¼
ä¹é¤ç®ã®æ¼ç®åã¯ããå·¦ããå³ãã«è©ä¾¡ãããã
*æ¼ç®åã¨/æ¼ç®åã®ãªãã©ã³ãã¯ãæ°å¤åãunscoped enumåã§ãªããã°ãªããªãã%æ¼ç®åã®ãªãã©ã³ãã¯ãæ´æ°åãunscoped enumåã§ãªããã°ãªããªãããªãã©ã³ãã«ã¯ãé常éãæ°å¤ã«é¢ããæ¨æºåå¤æãé©ç¨ããããå¼ãåç
§ã
*æ¼ç®åã¯ãä¹ç®ãæå³ããã
/æ¼ç®åã¯ãé¤ç®ãæå³ããã%æ¼ç®åã¯ã第ä¸ãªãã©ã³ãã第äºãªãã©ã³ãã§å²ã£ãä½ããæå³ããã第äºãªãã©ã³ãã®å¤ã0ã®å ´åã®æåã¯æªå®ç¾©ã§ããã/æ¼ç®åã®çµæã®åãæ´æ°ã®å ´åãå°æ°é¨åã¯åãæ¨ã¦ãããã
int main()
{
2 * 3 ; // 6
10 / 5 ; // 2
3 % 2 ; // 1
3 / 2 ; // çµæã¯æ´æ°åãå°æ°é¨åãåãæ¨ã¦ãããã®ã§ãçµæã¯1
3.0 / 2.0 ; // çµæã¯æµ®åå°æ°ç¹æ°åã®1.5
}
以ä¸ã¯ééã£ã¦ããä¾ã§ããã
// ãã®ã³ã¼ãã¯ééã£ã¦ããä¾
int main()
{
// ã¼ãé¤ç®
1 / 0 ;
// %æ¼ç®åã®ãªãã©ã³ãã«æµ®åå°æ°ç¹æ°åã¯ä½¿ããªã
3.0 % 2.0 ;
}
å¼ + å¼
å¼ - å¼
å æ¸ç®ã®æ¼ç®åã¯ããå·¦ããå³ãã«è©ä¾¡ãããã
両æ¹ã®ãªãã©ã³ããæ°å¤åã®å ´å
+æ¼ç®åã¯ãå ç®ãæå³ããã-æ¼ç®åã¯ãæ¸ç®ãæå³ããã-æ¼ç®åã®æ¸ç®ã¨ã¯ã第äºãªãã©ã³ãã®å¤ã第ä¸ãªãã©ã³ãããå¼ããã¨ã§ãããçµæã®åã«ã¯ãé常éãæ°å¤åã«é¢ããæ¨æºåå¤æãè¡ãããã
int main()
{
1 + 1 ; // 2
1 - 1 ; // 0
}
ãªãã©ã³ãããã¤ã³ã¿ã¼åã®å ´å
ã¾ãããã¤ã³ã¿ã¼ã®åã¯ãå®å
¨ã«å®ç¾©ããããªãã¸ã§ã¯ãã§ãªããã°ãªããªãããã¤ã³ã¿ã¼ã¯ãé
åã®è¦ç´ ãæã示ãã¦ãããã®ã¨ã¿ãªãããããã¨ãå®éã«ã¯é
åã®è¦ç´ ãæãã¦ããªãã¨ãã¦ããé
åã®è¦ç´ ãæãã¦ãããã®ã¨ã¿ãªãããã
+æ¼ç®åã®çæ¹ã®ãªãã©ã³ãããã¤ã³ã¿ã¼åã®å ´åãããçæ¹ã¯ãæ´æ°åã§ãªããã°ãªããªãã-æ¼ç®åã¯ã両æ¹ã®ãªãã©ã³ããåããã¤ã³ã¿ã¼åããå·¦ãªãã©ã³ãããã¤ã³ã¿ã¼åã§å³ãªãã©ã³ããæ´æ°åã§ãªããã°ãªããªãã
int main()
{
int array[3] ;
int * ptr = &array[1] ;
// OK
ptr + 1 ;
1 + ptr ;
ptr + (-1) ;
(-1) + ptr ;
ptr - ptr ;
ptr - 1 ;
ptr - (-1) ;
// ã¨ã©ã¼
ptr + ptr ; // +æ¼ç®åã®ä¸¡ãªãã©ã³ãããã¤ã³ã¿ã¼ã¨ãªã£ã¦ãã
1 - ptr ; // -æ¼ç®åã®å·¦ãªãã©ã³ããæ´æ°ã§å³ãªãã©ã³ãããã¤ã³ã¿ã¼ã¨ãªã£ã¦ãã
}
ãã¤ã³ã¿ã¼ã¨æ´æ°ã®å æ¸ç®ã®çµæã®åã¯ããã¤ã³ã¿ã¼ã®åã§ãããçµæã®å¤ã¯ããã¤ã³ã¿ã¼ãæãè¦ç´ ã«å¯¾ããé
åä¸ã®æ·»åã«ãæ´æ°ãå æ¸ç®ããè¦ç´ ãæããã®ã¨ãªããããããã¤ã³ã¿ã¼ãé
åã®æ·»åã§içªç®ã®è¦ç´ ãæã示ãã¦ããå ´åããã®ãã¤ã³ã¿ã¼ã«æ´æ°nãå ç®ãããã¨ã¯ãi + nçªç®ã®è¦ç´ ãæã示ããã¨ã«ãªããåæ§ã«ãã¦ãæ´æ°nãæ¸ç®ãããã¨ã¯ãi - nçªç®ã®è¦ç´ ãæã示ããã¨ã«ãªãã
int main()
{
int array[10] ;
int * ptr = &array[5] ;
ptr + 2 ; // &array[5 + 2]ã¨åã
ptr - 2 ; // &array[5 - 2]ã¨åã
}
ããããã¤ã³ã¿ã¼ããé
åã®æå¾ã®è¦ç´ ãæãã¦ããå ´åãããã«1ãå ããã¨ãçµæã®ãã¤ã³ã¿ã¼ã¯é
åã®æå¾ã®è¦ç´ ã®ã²ã¨ã¤å¾ããæããã¨ã«ãªãããã¤ã³ã¿ã¼ãé
åã®æå¾ã®è¦ç´ ã®ã²ã¨ã¤å¾ããæãã¦ããå ´åããããã1ãå¼ãã¨ãçµæã®ãã¤ã³ã¿ã¼ã¯é
åã®æå¾ã®è¦ç´ ãæããã¨ã«ãªãã
int main()
{
int array[10] ;
// é
åã®æå¾ã®è¦ç´ ãæã
int * ptr = &array[9] ;
// é
åã®æå¾ã®è¦ç´ ã®ã²ã¨ã¤å¾ããæã
int * one_past_the_last = ptr + 1 ;
// é
åã®æå¾ã®è¦ç´ ãæã
int * last = one_past_the_last - 1 ;
}
é
åã®æå¾ã®è¦ç´ ãæãã¦ãããã¤ã³ã¿ã¼ã«1ãå ç®ãã¦ãæå¾ã®è¦ç´ ã®ä¸ã¤å¾ã®è¦ç´ ãæãããã«ãã¦ããè¦æ ¼ä¸ããã¤ã³ã¿ã¼ã®å¤ã®ãªã¼ãã¼ããã¼ã¯èµ·ãããªãã¨ä¿è¨¼ããã¦ããã2ã¤ç®ä»¥éã®è¦ç´ ãæã示ããå ´åãæåã¯æªå®ç¾©ã§ããã
int main()
{
int a[1] ;
int * p1 = &a[0] ; // æå¾ã®è¦ç´
int * p2 = p1 + 1 ; // OKãæå¾ã®ä¸ã¤å¾ã®è¦ç´
int * p3 = p2 + 1 ; // æåã¯æªå®ç¾©
}
ä¸ã®ä¾ã§ãããããã¤ã³ã¿ã¼p2ãåç
§ããå ´åãæåã¯æªå®ç¾©ã ããp2èªä½ã¯æªå®ç¾©ã§ã¯ãªããp3ã¯æªå®ç¾©ã§ããã
ãã¤ã³ã¿ã¼å士ãæ¸ç®ããå ´åãçµæã¯ããã¤ã³ã¿ã¼ã®æãé
åã®æ·»åã®å·®ã«ãªãããã¤ã³ã¿ã¼Pãé
åã®æ·»åã§içªç®ã®è¦ç´ ãå·®ãã¦ããããã¤ã³ã¿ã¼Qãé
åã®æ·»åã§jçªç®ã®è¦ç´ ãæãã¦ããå ´åãP - Qã¯ãi - jã¨ãªããé
åã®æ·»åã¯ã0ããå§ã¾ããã¨ã«æ³¨æã両æ¹ã®ãã¤ã³ã¿ã¼ãåãé
åä¸ã®è¦ç´ ãå·®ãã¦ããªãå ´åãæåã¯æªå®ç¾©ã§ããã
int main()
{
int array[10] ;
int * P = &array[2] ;
int * Q = &array[7] ;
P - Q ; // 2 - 7 = -5
Q - P ; // 7 - 2 = 5
}
ãã¤ã³ã¿ã¼å士ã®æ¸ç®ã®çµæã®åã¯ãå®è£
ä¾åã§ãããã<cstddef>ãããã¼ã§å®ç¾©ããã¦ãããstd::ptrdiff_tã¨åãåã«ãªãã
0ã¨ããå¤ãããã¤ã³ã¿ã¼ã«è¶³ãå¼ããããå ´åãçµæã¯ããã®ãã¤ã³ã¿ã¼ã®å¤ã«ãªãã
void f( int * ptr )
{
ptr == ptr + 0 ; // true
ptr == ptr - 0 ; // true
}
å¼ << å¼
å¼ >> å¼
ã·ããæ¼ç®åã®ãªãã©ã³ãã¯ãæ´æ°åãunscoped enumåã§ãªããã°ãªããªãããªãã©ã³ãã«ã¯ãæ´æ°ã®ããã¢ã¼ã·ã§ã³ãè¡ããããçµæã®åã¯ãæ´æ°ã®ããã¢ã¼ã·ã§ã³ãè¡ãããå¾ã®ãªãã©ã³ãã®åã«ãªãã
å·¦ã·ãããE1 << E2ã®çµæã¯ãE1ãE2ããããå·¦ã«ã·ãããããã®ã¨ãªããã·ãããããå¾ã®ãããã¯ã0ã§åããããããããE1ã®åãunsignedãªãã°ãçµæã®å¤ã¯ãE1 à 2E2ããE1ã®æ大å¤+1ã§å°ä½ãããã®ã¨ãªãã
// ã³ã¡ã³ãå
ã®å¤ã¯2é²æ°ã§ããã
int main()
{
// 1101
unsigned int bits = 9 ;
bits << 1 ; // 11010
bits << 2 ; // 110100
}
E1ã®åãsignedã®å ´åãE1ãè² æ°ã§ãªããE1 à 2E2ã表ç¾å¯è½ã§ããã°ããã®å¤ã«ãªãããã®ä»ã®å ´åã¯æªå®ç¾©ã§ãããããã¯ãsignedãªæ´æ°åã®å
é¨è¡¨ç¾ã2ã®è£æ°ã§ããã¨ã¯ä¿è¨¼ãã¦ããªãã®ã§ããã®ããã«ãªã£ã¦ããã
// ã³ã¡ã³ãå
ã®å¤ã¯2é²æ°ã§ãã
int main()
{
// 1101
int bits = 9 ;
bits << 1 ; // 11010
bits << 2 ; // 110100
-1 << 1 ; // çµæã¯æªå®ç¾©
}
å³ã·ãããE1 >> E2ã®çµæã¯ãE1ãE2ããããå³ã«ã·ãããããã®ã¨ãªãããããE1ã®åãunsignedããsignedã§æ£ã®æ°ãªãã°ãçµæã®å¤ã¯ãE1 ÷ 2E2ã®æ´æ°é¨åã«ãªãã
// ã³ã¡ã³ãå
ã®å¤ã¯2é²æ°ã§ãã
int main()
{
// 1101
unsigned int value = 9 ;
value >> 1 ; // 110
value >> 2 ; // 11
int signed_value = 9 ;
signed_value >> 1 ; // 110
signed_value >> 2 ; // 11
}
E1ã®åãsignedã§ãå¤ãè² æ°ã®å ´åãæåã¯æªå®ç¾©ã§ããã
int main()
{
-1 >> 1 ; // çµæã¯æªå®ç¾©
}
å³ãªãã©ã³ãã®å¤ãè² æ°ã§ãã£ãããæ´æ°ã®ããã¼ã¢ã¼ã·ã§ã³å¾ã®å·¦ãªãã©ã³ãã®ãããæ°ä»¥ä¸ã®å ´åã®æåã¯æªå®ç¾©ã§ããã
// ãã®ç°å¢ã§ã¯ã1ãã¤ãã¯8ããã
// sizeof(unsigned int)ã¯2ã¨ããã
// ããªãã¡ããã®ç°å¢ã§ã¯ãunsigned intã¯16ãããã¨ãªãã
int main()
{
unsigned int value = 1 ;
value << -1 ; // æªå®ç¾©
value >> -1 ; // æªå®ç¾©
value << 16 ; // æªå®ç¾©
value >> 16 ; // æªå®ç¾©
value << 17 ; // æªå®ç¾©
value >> 17 ; // æªå®ç¾©
}
ã·ããæ¼ç®ã«ã¯ãæªå®ç¾©ã®é¨åãé常ã«å¤ãããã ããå¤ãã®ç¾å®ã®ç°å¢ã§ã¯ãä½ããã®å
·ä½çãªæå³ãå®ç¾©ããã¦ãã¦ãæã¨ãã¦ããã®ãããªæªå®ç¾©ã®æåã«ä¾åããã³ã¼ããæ¸ããªããã°ãªããªãå ´åãããããã®å ´åãç¹å®ã®ç°å¢ã«ä¾åããã³ã¼ãã ã¨ããæ£ããèªèãæããªããã°ãªããªãã
å¼ < å¼
å¼ > å¼
å¼ <= å¼
å¼ >= å¼
é¢ä¿æ¼ç®åã¯ãå·¦ããå³ãã«è©ä¾¡ãããã
é¢ä¿æ¼ç®åã®ãªãã©ã³ãã«ã¯ãæ°å¤åãenumåããã¤ã³ã¿ã¼åã使ããã¨ãã§ãããåæ¼ç®åã®æå³ã¯ã以ä¸ã®ããã«ãªã£ã¦ããã
- A < B
- Aã¯Bããå°ãã
- A > B
- Aã¯Bãã大ãã
- A <= B
- Aã¯Bããå°ããããçãã
- A >= B
- Aã¯Bãã大ããããçãã
çµæã®åã¯boolã¨ãªãã両ãªãã©ã³ããæ°å¤åãenumåã®å ´åãä¸çå·ã®é¢ä¿ãæ£ãããã°trueããããã§ãªããã°falseãè¿ãã
void f( int a, int b )
{
a < b ;
a > b ;
a <= b ;
a >= b ;
}
å¼ã®çµæã®åã¯boolã§ããã
ãã¤ã³ã¿ã¼å士ã®æ¯è¼ã«é¢ãã¦ã¯ãæªè¦å®ãªé¨åãå¤ããããã§ã¯ãè¦æ ¼ã«ããä¿è¨¼ããã¦ãããã¨ã ãã説æããã
åãåã®äºã¤ã®ãã¤ã³ã¿ã¼ãpã¨qããåããªãã¸ã§ã¯ããé¢æ°ãæãã¦ããå ´åããããã¯ãåãé
åã®æå¾ã®è¦ç´ ã®ã²ã¨ã¤å¾ã®è¦ç´ ãæãã¦ããå ´åããããã¯ã両æ¹ã¨ãnullã®å ´åã¯ãp<=qã¨p>=qã¯trueã¨ãªããp<qã¨p>qã¯falseã¨ãªãã
int main()
{
int object = 0 ;
int * p = &object ;
int * q = &object ;
p <= q ; // true
p >= q ; // true
p < q ; // false
p > q ; // false
}
åãåã®äºã¤ã®ãã¤ã³ã¿ã¼ãpã¨qããç°ãªããªãã¸ã§ã¯ããå·®ãã¦ããããã®ãªãã¸ã§ã¯ãã¯åããªãã¸ã§ã¯ãã®ã¡ã³ãã¼ã§ã¯ãªããã¾ãåãé
åå
ã®è¦ç´ ã§ã¯ãªããç°ãªãé¢æ°ã§ããªãããããã¯ãã©ã¡ããçæ¹ã®å¤ã®ã¿ãnullã®å ´åãp<q, p>q, p<=q, p>=qã®çµæã¯ãæªè¦å®ã§ããã
int main()
{
int object1 ;
int object2 ;
int * p = &object1 ;
int * q = &object2 ;
p <= q ; // çµæã¯æªè¦å®
p >= q ; // çµæã¯æªè¦å®
p < q ; // çµæã¯æªè¦å®
p > q ; // çµæã¯æªè¦å®
p < nullptr ; // çµæã¯æªè¦å®
}
åãåã®äºã¤ã®ãã¤ã³ã¿ã¼ãpã¨qããåãé
åã®è¦ç´ ãæãã¦ããå ´åãæ·»åã®å¤§ããè¦ç´ ã®æ¹ãããã大ããã¨è©ä¾¡ãããã
int main()
{
int array[2] ;
int * p = &array[0] ;
int * q = &array[1] ;
p < q ; // true
p > q ; // false
p <= q ; // true
p >= q ; // false
ããã¨åæ§ã«ãpã¨qãæãã¦ãããã®ããåãåã®åãã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã®ãµããªãã¸ã§ã¯ãã§ããå ´åã¯ãåãã¢ã¯ã»ã¹ã³ã³ããã¼ã«ä¸ã«ããå ´åãå¾ã«å®£è¨ãããã¡ã³ãã¼ã®æ¹ãããã¤ã³ã¿ã¼å士ã®æ¯è¼æ¼ç®ã§ã¯ã大ããã¨è©ä¾¡ãããã
struct S
{
// åãã¢ã¯ã»ã¹ã³ã³ããã¼ã«ä¸
int a ;
int b ; // bãå¾ã«å®£è¨ããã¦ãã
} ;
int main()
{
S object ;
// åããªãã¸ã§ã¯ãã®ãµããªãã¸ã§ã¯ã
int * p = &object.a ;
int * q = &object.b ;
p < q ; // true
p > q ; // false
} ;
ããã¨ä¼¼ã¦ãããããã ãã¯ã©ã¹ã®ã¡ã³ãã¼ã®ã¢ã¯ã»ã¹ã³ã³ããã¼ã«ãç°ãªãå ´åãçµæã¯æªè¦å®ã§ããã
struct S
{
public :
int a ;
private :
int b ;
void f()
{
&a < &b ; // çµæã¯æªè¦å®
}
} ;
äºã¤ã®ãã¤ã³ã¿ã¼ãpã¨qããunionã®åããªãã¸ã§ã¯ãã®éstaticãªãã¼ã¿ã¡ã³ãã¼ãæãã¦ããå ´åãçããã¨è©ä¾¡ãããã
union Object
{
int x ;
int y ;
} ;
int main()
{
Object object ;
int * p = &object.x ;
int * q = &object.y ;
p < q ; // false
p > q ; // false
p <= q ; // true
p >= q ; // true
p == q ; // true
}
äºã¤ã®ãã¤ã³ã¿ã¼ããåãé
åå
ã®è¦ç´ ãæãã¦ããå ´åãæ·»åã®å¤§ããè¦ç´ ãæããã¤ã³ã¿ã¼ãã大ããã¨è©ä¾¡ããããã¾ããããã¯ã©ã¡ããçæ¹ã®ãã¤ã³ã¿ã¼ããé
åã®ç¯å²ãè¶
ãã¦ãã¦ããè©ä¾¡ã§ããã
int main()
{
int a[2] ;
int * p1 = &a[0] ;
int * p2 = &a[1] ;
p1 < p2 ; // true
int * p3 = p2 + 1 ; // p3ã¯é
åã®ç¯å²å¤ãæã
p1 < p3 ; // OKãçµæã¯true
}
voidã¸ã®ãã¤ã³ã¿ã¼åã¯ãæ¯è¼ãããã¨ãã§ãããã¾ããçæ¹ã®ãªãã©ã³ããvoidã¸ã®ãã¤ã³ã¿ã¼åã§ãããçæ¹ãå¥ã®ãã¤ã³ã¿ã¼åã§ããå ´åãããçæ¹ã®ãªãã©ã³ãããæ¨æºåå¤æã«ãã£ã¦voidã¸ã®ãã¤ã³ã¿ã¼åã«å¤æãããã®ã§ãæ¯è¼ãããã¨ãã§ãããããã両æ¹ã®ãã¤ã³ã¿ã¼ããåãã¢ãã¬ã¹ã§ãã£ãå ´åãnullãã¤ã³ã¿ã¼ã®å ´åã¯ãçããã¨è©ä¾¡ãããããã以å¤ã¯ãæªè¦å®ã§ããã
int main()
{
int object = 0 ;
int * ptr = &object ;
void * p = ptr ;
void * q = ptr ;
p < q ; // false
p > q ; // false
p <= q ; // true
p >= q ; // true
// æ¨æºåå¤æã«ãã£ã¦ãå¥ã®ãã¤ã³ã¿ã¼åã¨ãæ¯è¼ã§ãã
p <= ptr ; // true
}
ãã以å¤ã®æ¯è¼ã®çµæã¯ããã¹ã¦æªè¦å®ã¨ãªã£ã¦ãããæªå®ç¾©ã§ã¯ãªããæªè¦å®ãªã®ã§ãå®è£
ã«ãã£ã¦ã¯ãæå³ã®ããçµæãè¿ããã¨ããããããããå®è£
ã«ä¾åããæåãªã®ã§ã移æ¤æ§ã«æ¬ ããã
å¼ == å¼
å¼ != å¼
==æ¼ç®åï¼çããï¼ã¨ã!=æ¼ç®åï¼çãããªãï¼ã¯ãé¢ä¿æ¼ç®åã¨ãªãã©ã³ããçµæã®åãè©ä¾¡ã®æ¹æ³ã¯åãã§ããããã ãæ¯è¼ã®æå³ã¯ããçããããããçãããªãããã§ããã
int main()
{
1 == 1 ; // true
1 != 1 ; // false
1 == 2 ; // false
1 != 2 ; // true
}
åãåã®ãã¤ã³ã¿ã¼ã®å ´åãã¨ãã«ã¢ãã¬ã¹ãåãããã¨ãã«nullãã¤ã³ã¿ã¼ã®å ´åãtrueã¨è©ä¾¡ãããã
==æ¼ç®åã¯ã代å
¥æ¼ç®åã§ãã=æ¼ç®åã¨ééããããã®ã§ã注æããªããã°ãªããªãã
void f( int x )
{
if ( x = 1 ) // ééã
{
// å¦ç
} else {
// å¦ç
}
}
ãã®ä¾ã§ã¯ãifæã®æ¡ä»¶å¼ã®çµæã¯ã代å
¥å¼ã®çµæã¨ãªã£ã¦ãã¾ããããã¯ã1ã§ããã®ã§ããã®ifæã¯å¸¸ã«trueã§ããã¨è©ä¾¡ããã¦ãã¾ãã
å¼ & å¼
ãããåè«çç©æ¼ç®åã¯ã両ãªãã©ã³ãã®åããããã¨ã®è«çç©ï¼ANDï¼ãè¿ãããªãã©ã³ãã¯æ´æ°åããunscoped enumåã§ãªããã°ãªããªãã
å¼ ^ å¼
ãããåæä»çè«çåæ¼ç®åã¯ã両ãªãã©ã³ãã®åããããã¨ã®æä»çè«çåï¼exclusive ORï¼ãè¿ãããªãã©ã³ãã¯æ´æ°åããunscoped enumåã§ãªããã°ãªããªãã
å¼ | å¼
ãããåè«çåæ¼ç®åã¯ã両ãªãã©ã³ãã®åããããã¨ã®è«çåï¼inclusive ORï¼ãè¿ãããªãã©ã³ãã¯æ´æ°åããunscoped enumåã§ãªããã°ãªããªãã
å¼ && å¼
&&æ¼ç®åã¯ãå·¦ããå³ãã«è©ä¾¡ãããã
è«çç©æ¼ç®åã¯ããªãã©ã³ãã®è«çç©ãè¿ãæ¼ç®åã§ããã両ãªãã©ã³ãã¯boolã«å¤æããããçµæã®åã¯boolã§ããã両æ¹ã®ãªãã©ã³ããtrueã§ããã°ãçµæã¯trueããã以å¤ã¯falseã¨ãªãã
true && true ; // true
true && false ; // false
false && true ; // false
false && false ; // false
第ä¸ãªãã©ã³ããè©ä¾¡ããçµæãfalseã®å ´åã第äºãªãã©ã³ãã¯è©ä¾¡ãããªãããªããªãã°ã第ä¸ãªãã©ã³ããfalseã§ããã°ã第äºãªãã©ã³ããè©ä¾¡ããã¾ã§ããªããçµæã¯falseã§ããã¨æ±ºå®ã§ããããã§ããã
bool f() { return false ; }
bool g() { return true ; }
int main()
{
// g()ã¯å¼ã°ããªããçµæã¯false
f() && g() ;
}
ãã®ä¾ã§ã¯ã第ä¸ãªãã©ã³ãã§ããé¢æ°fã®å¼ã³åºãã¯falseãè¿ãã®ã§ã第äºãªãã©ã³ãã®é¢æ°gã®å¼ã³åºããè©ä¾¡ããããã¨ã¯ãªããã¤ã¾ããé¢æ°gã¯å¼ã°ããªãã
第äºãªãã©ã³ããè©ä¾¡ãããæã第ä¸ãªãã©ã³ãã®è©ä¾¡ã«ãã£ã¦çããå¤ã®è¨ç®ãå¯ä½ç¨ã¯ããã¹ã¦è¡ããã¦ããã
int main()
{
int value = 0 ;
++value // å¤ã¯1ã«ãªãã®ã§ãtrueã¨è©ä¾¡ããã
&&
value ; // å¤ã¯ãã§ã«1ã¨ãªã£ã¦ããã®ã§ãtrueã¨è©ä¾¡ããã
}
å¼ || å¼
||æ¼ç®åã¯ããå·¦ããå³ãã«è©ä¾¡ãããã
è«çåæ¼ç®åã¯ããªãã©ã³ãã®è«çåãè¿ãæ¼ç®åã§ããã両ãªãã©ã³ãã¯boolã«å¤æããããçµæã®åã¯boolã§ããããªãã©ã³ããçæ¹ã§ãtrueã¨è©ä¾¡ãããå ´åãçµæã¯trueã¨ãªãã両ãªãã©ã³ããfalseã®å ´åã«ãçµæã¯falseã¨ãªãã
int main()
{
true || true ; // true
true || false ; // true
false || true ; // true
false || false ; // false
}
第ä¸ãªãã©ã³ããè©ä¾¡ããçµæãtrueã®å ´åã第äºãªãã©ã³ãã¯è©ä¾¡ãããªãããªããªãã°ã第ä¸ãªãã©ã³ããtrueã§ããã°ã第äºãªãã©ã³ããè©ä¾¡ããã¾ã§ããªããçµæã¯trueã¨ãªãããã§ããã
bool f() { return true ; }
bool g() { return false ; }
int main()
{
// g()ã¯å¼ã°ããªããçµæã¯true
f() || g() ;
}
è«çç©ã¨åãããã«ã第äºãªãã©ã³ããè©ä¾¡ãããå ´åã第ä¸ãªãã©ã³ãã®è©ä¾¡ã«ãã£ã¦çããå¤ã®è¨ç®ãå¯ä½ç¨ã¯ããã¹ã¦è¡ããã¦ããã
å¼ ? å¼ : 代å
¥å¼
æ¡ä»¶æ¼ç®åã¯ãå·¦ããå³ãã«è©ä¾¡ãããã
æ¡ä»¶æ¼ç®åã¯ãä¸ã¤ã®ãªãã©ã³ããåããC++ã«ã¯ä»ã«ä¸ã¤ã®ãªãã©ã³ããåãæ¼ç®åããªããã¨ãããä¸é
æ¼ç®åã¨ããã°ãæ¡ä»¶æ¼ç®åã®ä»£åè©ã®ããã«ä½¿ããã¦ãããããããæ£å¼å称ã¯æ¡ä»¶å¼ã§ãããæ¼ç®åã®å称ã¯æ¡ä»¶æ¼ç®åã§ããã
æ¡ä»¶æ¼ç®åã®ç¬¬ä¸ãªãã©ã³ãã¯boolã«å¤æããããå¤ãtrueã§ããã°ã第äºãªãã©ã³ãã®å¼ãè©ä¾¡ããããã®çµæãè¿ããããå¤ãfalseã§ããã°ã第ä¸ãªãã©ã³ãã®å¼ãè©ä¾¡ããããã®çµæãè¿ãããã第äºãªãã©ã³ãã¨ç¬¬ä¸ãªãã©ã³ãã¯ãã©ã¡ããçæ¹ããè©ä¾¡ãããªãã
bool cond() ;
int e1() ;
int e2() ;
int main()
{
true ? 1 : 2 ; // 1
false ? 1 : 2 ; // 2
// é¢æ°condã®æ»ãå¤ã«ãã£ã¦ãé¢æ°e1ããããã¯e2ãå¼ã°ãããã®æ»ãå¤ãè¿ãããã
// e1ã¨e2ã¯ãã©ã¡ããçæ¹ããå¼ã°ããªãã
cond() ? e1() : e2() ;
}
å®ã¯ãæ¡ä»¶æ¼ç®åã¯è¦ãç®ã»ã©ç°¡åã§ã¯ãªããç¹ã«ãçµæã®åãã©ã®ããã«ãã¦æ±ºå®ãããã¨ãããã¨ããé常ã«é£ãããããã§ã¯ãçµæã®åã決å®ããå®å
¨ãªè©³ç´°ã¯èª¬æããªãããç¹ã«éè¦ã ã¨æãããäºãåããããã
æ¡ä»¶æ¼ç®åã®ç¬¬äºç¬¬ä¸ãªãã©ã³ãã«ã¯ãçµæãvoidåã¨ãªãå¼ã使ããã¨ãã§ããã
void f() {}
int main()
{
true ? f() : f() ;
int * ptr = new int ;
true ? delete ptr : delete ptr ;
true ? throw 0 : throw 0 ;
}
çæ¹ã®ãªãã©ã³ããvoidã§ãããçæ¹ãvoidã§ã¯ãªãå ´åãã¨ã©ã¼ã§ããã
void f() {}
int main()
{
true ? 0 : f() ; // ã¨ã©ã¼
true ? f() : 0 ; // ã¨ã©ã¼
}
ãã ããçæ¹ã®ãªãã©ã³ããthrowå¼ã®å ´åã«éããããçæ¹ã®ãªãã©ã³ãã«ãvoidã§ã¯ãªãå¼ã§ã使ããã¨ãã§ãããçµæã¯prvalueã®å¤ã§ãåã¯throwå¼ã§ã¯ãªãæ¹ã®ãªãã©ã³ãã®åã«ãªãã
void f() {}
int main()
{
// OK
// xã«0ã代å
¥ãã
int x = true ? 0 : throw 0 ;
// ã¨ã©ã¼
// æ»ãå¤ã«123ã代å
¥ãããã¨ãã¦ããããprvalueã«ã¯ä»£å
¥ã§ããªã
(true ? x : throw 0) = 123 ;
true ? throw 0 : f() ; // OK
}
両ãªãã©ã³ãããã¨ãã«åãå¤ã«ãã´ãªã¼ã§ãåãåã®å ´åã¯ãæ¡ä»¶æ¼ç®åã®çµæã¯ããã®å¤ã«ãã´ãªã¼ã¨åã«ãªãã
int f() { return 0 ; }
int main()
{
int x = 0 ;
// 両ãªãã©ã³ãã¨ããlvalueã®intå
// çµæã¯lvalueã®int
( true ? x : x ) = 0 ; // lvalueãªã®ã§ä»£å
¥ãå¯è½
// 両ãªãã©ã³ãã¨ããxvalueã®intå
// çµæã¯xvalueã®int
true ? std::move(x) : std::move(x) ;
// 両ãªãã©ã³ãã¨ããprvalueã®intå
// çµæã¯prvalueã®int
true ? f() : f() ;
}
ããããªãã©ã³ãã®å¤ã«ãã´ãªã¼ãåãéãå ´åãæé»ã®åå¤æã«ãã£ã¦ããäºãã®åã¨å¤ã«ãã´ãªã¼ãä¸è´ããããã¨ãã試ã¿ããªãããããã®å¤æã®è©³ç´°ã¯ãé常ã«è¤éã§ãé常ã¯æèããå¿
è¦ã¯ãªããããæ¬æ¸ã§ã¯çç¥ããã
å¼ ä»£å
¥æ¼ç®å å¼
代å
¥æ¼ç®å:以ä¸ã®ãã¡ã©ãã
= *= /= %= += -= >>= <<= &= ^= |=
代å
¥æ¼ç®åï¼=ï¼ã¨ãè¤å代å
¥æ¼ç®åã¯ããå³ããå·¦ãã«è©ä¾¡ãããã
代å
¥æ¼ç®åã¯ãå·¦å´ã®ãªãã©ã³ãã«ãå³å´ã®ãªãã©ã³ãã®å¤ã代å
¥ãããå·¦å´ã®ãªãã©ã³ãã¯å¤æ´å¯è½ãªlvalueã§ãªããã°ãªããªããçµæã¨ãã¦ãå·¦å´ã®ãªãã©ã³ãã®lvalueãè¿ãã
int main()
{
int x ;
x = 0 ;
}
åæåã¨æ··åããªãããã«æ³¨æã
int main()
{
int x = 0 ; // ããã¯åæå
x = 0 ; // ããã¯ä»£å
¥
}
=ã代å
¥æ¼ç®åã¨ããããã®ä»ã®æ¼ç®åããè¤å代å
¥æ¼ç®åã¨ããã
ã¯ã©ã¹ã®ä»£å
¥ã«é¢ãã詳細ã¯ãã¯ã©ã¹ãªãã¸ã§ã¯ãã®ã³ãã¼ã¨ã ã¼ããããªã¼ãã¼ãã¼ãã®ä»£å
¥ãåç
§ã
è¤å代å
¥æ¼ç®åã®å¼ãE1 op = E2ã¯ãE1 = E1 op E2ã¨åãã§ããããã ããE1ã¨ããå¼ã¯ãä¸åº¦ããè©ä¾¡ãããªããopã«ã¯ãä»»æã®è¤å代å
¥æ¼ç®åã®ä¸é¨ãå
¥ãã
int main()
{
int x = 0 ;
x += 1 ; // x = x + 1ã¨åã
x *= 2 ; // x = x * 2ã¨åã
}
å³å´ã®ãªãã©ã³ãã«ã¯ãåæåãªã¹ãã使ããã¨ãã§ããã
å·¦å´ã®ãªãã©ã³ããã¹ã«ã©ã¼åã®å ´åãããåTã®å¤æ°ãxã¨ããã¨ãx = {v}ã¨ããå¼ã¯ãx = T(v)ã¨ããå¼ã¨åãæå³ã«ãªãããã ããåæåãªã¹ããªã®ã§ã縮å°å¤æã¯ç¦æ¢ããã¦ãããx = {}ã¨ããå¼ã¯ãx = T()ã¨ããå¼ã¨åãæå³ã«ãªãã
int main()
{
int x ;
x = {1} ; // x = int(1) ã¨åã
x = {} ; // x = int()ã¨åã
short s ;
s = {x} ; // ã¨ã©ã¼ã縮å°å¤æã¯ç¦æ¢ããã¦ããã
}
ãã以å¤ã®å ´åã¯ãåæåãªã¹ããå®å¼æ°ã¨ãã¦ãã¦ã¼ã¶ã¼å®ç¾©ã®ä»£å
¥æ¼ç®åãå¼ã³åºãããã
struct C
{
C(){}
C( std::initializer_list<int> ) {}
} ;
int main()
{
C c ;
c = { 1, 2, 3 } ;
}
å¼ , å¼
ã³ã³ãæ¼ç®åã¯ããå·¦ããå³ãã«è©ä¾¡ãããã
ã³ã³ãæ¼ç®åã¯ãã¾ãå·¦ã®ãªãã©ã³ãã®å¼ãè©ä¾¡ããã次ã«ãå³ã®ãªãã©ã³ãã®å¼ãè©ä¾¡ããããå·¦ã®ãªãã©ã³ãã®å¼ãè©ä¾¡ããçµæã¯ç ´æ£ãããå³ã®ãªãã©ã³ãã®çµæããã³ã³ãæ¼ç®åã®çµæã¨ãã¦ããã®ã¾ã¾è¿ããããçµæã®åãå¤ãå¤ã«ãã´ãªã¼ã¯ãå³ã®ãªãã©ã³ãã®å¼ãè©ä¾¡ããçµæã¨å
¨ãããªãã«ãªãã
int main()
{
1, 2 ; // 2
1, 2, 3, 4, 5 ; // 5
}
å³ã®ãªãã©ã³ãã®å¼ãè©ä¾¡ãããåã«ãå·¦ã®ãªãã©ã³ãã®å¼ã®å¤è¨ç®ãå¯ä½ç¨ã¯ããã§ã«è¡ããã¦ããã
int f() ;
int g() ;
int main()
{
int i = 0 ;
// å·¦ã®ãªãã©ã³ãã®iã¯ããã§ã«ã¤ã³ã¯ãªã¡ã³ãããã¦ããã
++i, i ;
// é¢æ°gãå¼ã°ããåã«ãé¢æ°fã¯ãã§ã«å¼ã°ãçµãã£ã¦ããã
f() , g() ;
}
ã³ã³ããç¹å¥ãªæå³ãæã¤å ´é¢ã§ã¯ãã³ã³ãæ¼ç®åã使ãã«ã¯ãæ示çã«æ¬å¼§ã§å²ã¾ãªããã°ãªããªããã³ã³ããç¹å¥ãªæå³ãæã¤å ´é¢ã«ã¯ãä¾ãã°ãé¢æ°ã®å®å¼æ°ãªã¹ãããåæåãªã¹ããªã©ãããã
void f(int, int, int) {}
int main()
{
int x ;
// æ¬å¼§ãå¿
è¦
f( 1, (x=0, x), 2) ;
}
ãã®ä¾ã§ã¯ãé¢æ°fã¯ä¸ã¤ã®å¼æ°ãåããäºã¤ãã®å¼æ°ã¯ãæ¬å¼§å¼ã«å²ã¾ããã³ã³ãæ¼ç®åã®å¼ã§ãããããã¯å¤æ°xã«0ã代å
¥ããå¾ããã®xãå¼æ°ã¨ãã¦æ¸¡ãã¦ããã
å®æ°å¼ï¼constant expressionï¼ã¨ã¯ãå¤ãã³ã³ãã¤ã«æã«æ±ºå®ã§ããå¼ã®ãã¨ã§ãããå®æ°å¼ãã©ããã¨ãããã¨ã¯ãC++ã®ããã¤ãã®å ´é¢ã§ãéè¦ã«ãªã£ã¦ãããä¾ãã°ãé
åã宣è¨ããæãè¦ç´ æ°ã¯å®æ°å¼ã§ãªããã°ãªããªãã
int main()
{
// æ´æ°ãªãã©ã«ã¯å®æ°å¼
int a[5] ;
// const修飾ããã¦ãã¦ãåæåå¼ãå®æ°å¼ã§ãããªãã¸ã§ã¯ãã¯å®æ°å¼
int const n = 5 ;
int b[n] ; // OK
int m = 5 ; // ããã¯å®æ°å¼ã§ã¯ãªã
int c[m] ; // ã¨ã©ã¼
}
注æï¼ãã®è§£èª¬ã¯ãC++14ã®ãã©ããN3797ãåèã«ãã¦ãããæ£å¼ãªC++14è¦æ ¼ã§ã¯å¤æ´ãããå¯è½æ§ããããã¾ããC++11ã§ã¯ãªãã
ããå¼eãè©ä¾¡ããéã«ã以ä¸ã«æããå¼ãè©ä¾¡ããªãå ´åãå¼eã¯ã³ã¢å®æ°å¼(core constant expression)ã§ããã
-
thisããã ããeã®ä¸é¨ã¨ãã¦è©ä¾¡ãããconstexpré¢æ°ãconstexprã³ã³ã¹ãã©ã¯ã¿ã¼å
ãé¤ã
-
ãªãã©ã«ã¯ã©ã¹ã®constexprã³ã³ã¹ãã©ã¯ã¿ã¼ãconstexpré¢æ°ãããªãã¢ã«ãã¹ãã©ã¯ã¿ã¼ã®æé»ã®å¼ã³åºããé¤ããé¢æ°ã®å¼ã³åºã
-
æªå®ç¾©ã®constexpré¢æ°ãæªå®ç¾©ã®constexprã³ã³ã¹ãã©ã¯ã¿ã¼ã®å¼ã³åºã
-
å®è£
ã®å¶ç´ãè¶
ããå¼
å®è£
ã®å¶ç´ã¨ã¯ãä»®å¼æ°ããã³ãã¬ã¼ãä»®å¼æ°ã®æ°ã®æ大å¤ã®ãããªãã³ã³ãã¥ã¼ã¿ã¼ãæéã§ãããã¨ã«èµ·å ããæ§ã
ãªå¶ç´ã
-
æªå®ç¾©ã®æåãå«ãå¦ç
ä¾ãã°ã符å·ä»ãæ´æ°ã®ãªã¼ãã¼ããã¼ããä¸é¨ã®ãã¤ã³ã¿ã¼æ¼ç®ããã¼ãé¤ç®ããä¸é¨ã®ã·ããæ¼ç®ãªã©ã
-
ã©ã ãå¼
-
lvalueããrvalueã¸ã®å¤æããã ã以ä¸ã®å ´åãé¤ã
-
évolatileã®glvalueã®æ´æ°ãenumã®åããåæååãå®æ°å¼ã«ããåæåå¾ã®évolatileã®constãªãã¸ã§ã¯ããåç
§ããå ´å
æååãªãã©ã«ã«ããé
åã該å½ãã
-
évolatileã®glvalueããconstexprã§å®ç¾©ãããévolatileãªãã¸ã§ã¯ããããã®ãããªãªãã¸ã§ã¯ãã®å¤æ´å¯è½ãªãµããªãã¸ã§ã¯ããåç
§ããå ´å
-
évolatileã®ãªãã©ã«åã®glvalueããå¼eã®åæåã«ã¨ããªã£ã¦å¯¿å½ãéå§ããévolatileãªãã¸ã§ã¯ããåç
§ããæ
-
lvalueããrvalueã¸ã®å¤æããunionã®ä½¿ããã¦ããªãã¡ã³ãã¼ããµããªãã¸ã§ã¯ããåç
§ããglvalueã®å¤æ´
-
ãªãã¡ã¬ã³ã¹åã®å¤æ°ããã¼ã¿ã¡ã³ãã¼ãåç
§ããååããã ãããªãã¡ã¬ã³ã¹ã以ä¸ã®ããããã®æ¹æ³ã§åæåãããå¾ã®å ´åãé¤ãã
-
å®æ°å¼ã§åæåãããå ´å
-
å¼eã®è©ä¾¡ã¨ã¨ãã«å¯¿å½ãå§ã¾ã£ããªãã¸ã§ã¯ãã®éstaticãã¼ã¿ã¡ã³ãã¼
-
cv void *ãããªãã¸ã§ã¯ãã¸ã®ãã¤ã³ã¿ã¼åã¸ã®åå¤æ
-
dynamic_cast
-
reinterpret_cast
-
çä¼¼ãã¹ãã©ã¯ã¿ã¼å¼ã³åºã
-
ãªãã¸ã§ã¯ãã®å¤æ´ããã ããå¼eã®è©ä¾¡ã¨ã¨ãã«å¯¿å½ãå§ã¾ã£ãévolatileãªãã¸ã§ã¯ããåç
§ããévolatileã®ãªãã©ã«åã®lvalueã«å¯¾ãã¦é©ç¨ããããã®ãé¤ã
-
ããªã¢ã¼ãã£ãã¯ãªã¯ã©ã¹åã®glvalueããªãã©ã³ãã«æå®ããtypeidå¼
-
newå¼
-
deleteå¼
-
çµæãæªè¦å®ã¨ãªãæ¯è¼æ¼ç®åã¨çå·ãä¸çå·æ¼ç®å
-
throwå¼
å¼ãæ´æ°åãã¹ã³ã¼ããªãenumåã§ãæé»ã«prvalueã«åå¤æã§ããåå¤æããå¼ãã³ã¢å®æ°å¼ã§ãããããªå¼ããæ´æ°å®æ°å¼(integral constant expression)ã¨ããã
ãã®ãããªæ´æ°å®æ°å¼ã¯ãé
åã®å®£è¨ã®æ·»åããããããã£ã¼ã«ãããenumåæååããã¢ã©ã¤ã¡ã³ããªã©ã«ä½¿ããã
Tåã«å¤æãããå®æ°å¼(converted constant expression)ã¨ã¯ãæé»ã«Tåã®prvalueã«å¤æãããå¼ã®ãã¨ã§ããã®å¤æãããå¼ãã³ã¢å®æ°å¼ã§ãæé»ã®åå¤æã«ã¯ãã¦ã¼ã¶ã¼å®ç¾©åå¤æãlvalueããrvalueã¸ã®å¤æãæ´æ°ã®ããã¢ã¼ã·ã§ã³ãããã¼å¤æ以å¤ã®æ´æ°ã®åå¤æã ãã使ããã¦ãããã®ãè¨ãã
å¤æãããå®æ°å¼ã¯ãnewå¼ãcaseå¼ãå
é¨åãåºå®ãããenumåæååãé
åã®ç¯å²ãªã©ãæ´æ°ãenumã®éåãã³ãã¬ã¼ãå®å¼æ°ãªã©ãåå¤æãå¿
è¦ãªå®æ°å¼ã®æèã§ä½¿ãããã
ããã¾ã§è§£èª¬ãã¦ãå§ãã¦å®æ°å¼ã®å®ç¾©ãã§ããããã«ãªãã
å®æ°å¼(constant expression)ã¨ã¯ã³ã¢å®æ°å¼ã®ãã¡ãglvalueã®staticã¹ãã¬ã¼ã¸ããé¢æ°ããprvalueã³ã¢å®æ°å¼ã§ããã
prvalueã³ã¢å®æ°å¼ã®å ´åããã®å¤ã®ãªãã¸ã§ã¯ãã¨ãµããªãã¸ã§ã¯ããã以ä¸ã®æ¡ä»¶ããã¹ã¦æºããå ´åã®ã¿ãå®æ°å¼ã«ãªãã
-
ãªãã¡ã¬ã³ã¹åã®éstaticãã¼ã¿ã¡ã³ãã¼ã¯ãã¹ã¦ãstaticã¹ãã¬ã¼ã¸ä¸ã®ãªãã¸ã§ã¯ãããé¢æ°ãåç
§ãã¦ãããã¨
-
ãªãã¸ã§ã¯ãããµããªãã¸ã§ã¯ãããã¤ã³ã¿ã¼åã®å ´åããã®å¤ã¯ãstaticã¹ãã¬ã¼ã¸ä¸ã®ãªãã¸ã§ã¯ãã¸ã®ã¢ãã¬ã¹ããstaticã¹ãã¬ã¼ã¸ä¸ã®ãªãã¸ã§ã¯ããè¶
ããã¢ãã¬ã¹ããé¢æ°ã®ã¢ãã¬ã¹ããnullãã¤ã³ã¿ã¼ã§ãããã¨
C++è¦æ ¼ã¯ãæµ®åå°æ°ç¹æ°ã®è¨ç®ç²¾åº¦ãè¦å®ãã¦ããªããããC++ã®å®è£
ã§ã³ã³ãã¤ã«æã¨å®è¡æã§ãæµ®åå°æ°ç¹æ°ã®è¨ç®çµæãå¤ãã£ãã¨ãã¦ãããã®å®è£
ã¯è¦æ ¼æºæ ã§ããã
bool f()
{
char array[ 1 + int( 1 + 0.2 - 0.1 - 0.1 ) ] ; // ã³ã³ãã¤ã«æè©ä¾¡ããã
int size = 1 + int( 1 + 0.2 - 0.1 - 0.1 ) ; // å®è¡æè©ä¾¡ãããå¯è½æ§ããã
return sizeof( array ) == size ;
}
ãã®ãããªé¢æ°fã®æ»ãå¤ãtrueãfalseããC++è¦æ ¼ã¯è¦å®ãããã¨ãã§ããªãã
ãªãã©ã«ã¯ã©ã¹åã®å¼ããæ´æ°å®æ°å¼ãå¿
è¦ã¨ããæèã§ç¨ããããå ´åããã®å¼ã¯æèä¸ãæ´æ°åãã¹ã³ã¼ããªãenumåã«æé»ã«å¤æãããããã®å ´åã«ä½¿ãããå¤æé¢æ°ã¯ãconstexprã§ãªããã°ãªããªãã
èå¥å : æ
case å®æ°å¼ : æ
default : æ
æã«ã¯ã©ãã«ãä»ãããã¨ãã§ãããã©ãã«ã¨ã¯ããã®æãæãèå¥åã§ãããæã«ã©ãã«ãä»ããããã®æããã©ãã«æï¼label statementï¼ã¨ãããã©ãã«æã«ã¯ãå¿
ãå¾ç¶ããæãåå¨ããªããã°ãªããªãã
void f()
{
label :
// ã¨ã©ã¼ãã©ãã«ã«ç¶ãæããªã
} // ãããã¯ã®çµãã
void g()
{
// OKãã©ãã«ã«ç¶ãæããã
label_1 : /* å¼æ */ ;
label_2 : { /* è¤åæ */ } ;
}
èå¥åã©ãã«ï¼identifier labelï¼ã¯ãèå¥åã宣è¨ããããã®èå¥åã¯ãgotoæã§ãã使ããªãã
int main()
{
label_1 : ;
label_2 : ;
label_3 : ;
goto label_2 ;
}
ã©ãã«ã®èå¥åã®ã¹ã³ã¼ãã¯ã宣è¨ãããé¢æ°å
ã§ãããã©ãã«ãå宣è¨ãããã¨ã¯ã§ããªããã©ãã«ã®èå¥åã¯ã宣è¨ããåã«gotoæã§ä½¿ããã¨ãã§ããã
// ã©ãã«ã®ã¹ã³ã¼ãã¯ã宣è¨ãããé¢æ°å
void f() { label_f : ; }
void g()
{
goto label_f ; // ã¨ã©ã¼ããã®é¢æ°ã®ã¹ã³ã¼ãã®ã©ãã«ã§ã¯ãªã
}
// ã©ãã«ãå宣è¨ãããã¨ã¯ã§ããªã
void h()
{
label_h : ; // label_hã®å®£è¨
label_h : ; // ã¨ã©ã¼ãã©ãã«ã®å宣è¨ã¯ã§ããªã
}
// ã©ãã«ã®èå¥åã¯ã宣è¨ããåã«gotoæã§ä½¿ããã¨ãã§ãã
void i()
{
// èå¥ålabel_iã¯ããã®æç¹ã§ã¯ãã¾ã 宣è¨ããã¦ããªããã使ããã¨ãã§ãã
goto label_i ;
label_i ;
}
ã©ãã«ã®èå¥åã¯ãç¬èªã®åå空éãæã¤ã®ã§ãä»ã®èå¥åã¨æ··åããããã¨ã¯ãªãã
int main()
{
identifier : ; // ã©ãã«ã®èå¥å
int identifier ; // å¤æ°ã®èå¥å
goto identifier ; // ã©ãã«ã®èå¥åã使ããã
identifier = 0 ; // å¤æ°ã®èå¥åã使ããã
}
caseã©ãã«ã¨defaultã©ãã«ã¯ãswitchæã®ä¸ã§ãã使ããã¨ãã§ããªãã
int main()
{
switch(0)
{
case 0 : ;
default : ;
}
}
å¼opt ;
å¼æï¼expression statementï¼ã¨ã¯ãå¼ãæ¸ãäºã®ã§ããæã§ãããæã®å¤ãã¯ããã®å¼æã«è©²å½ãããå¼æã¯ãã»ãã³ãã³ï¼;ï¼ãçµç«¯è¨å·ã¨ãã¦ç¨ãããå¼æã¯ãæ¸ããã¦ããå¼ãè©ä¾¡ããã
int main()
{
0 ; // å¼ã¯0
1 + 1 ; // å¼ã¯1 + 1
// ããã¯å¼æã§ã¯ãªããreturnæ
return 0 ;
}
å¼æã¯ãå¼ãçç¥ãããã¨ãã§ãããå¼ãçç¥ããå¼æããnullæã¨ããã
/* å¼ãçç¥*/ ; // nullæ
;;;; // nullæãåã¤
;;;;;;;; // nullæãå
«ã¤
nullæã¯ãè©ä¾¡ãã¹ãå¼ããªãã®ã§ãä½ãããªãæã§ãããnullæã¯ãã¨ãã°ããããã¯ã®çµãã«ã©ãã«æãæ¸ãããå ´åããforæãwhileæã®ãããªã«ã¼ãããåã«åãããå ´åãªã©ã«ã使ããã¨ãã§ããã
int main()
{
// åã«ã«ã¼ããåãã ãã®foræ
for ( int i = 0 ; i != 10 ; ++i ) ;
label : ; // ã©ãã«æã«ã¯ãå¾ç¶ããæãå¿
è¦ã
}
{ ã²ã¨ã¤ä»¥ä¸ã®æopt }
è¤åæãã¾ãã¯ãããã¯ã¨ããæã¯ãæãã²ã¨ã¤ããæ¸ããªãå ´æã«ãè¤æ°ã®æãæ¸ããã¨ãã§ããæã§ããã
void f( bool b )
{
if ( b )
/*ããã«ã¯ã²ã¨ã¤ã®æããæ¸ããªã*/ ;
if ( b )
{
// ãããã§ã好ããªã ãæãæ¸ããã¨ãã§ããã
}
}
è¤åæã¯ããããã¯ã¹ã³ã¼ããå®ç¾©ããã
int main()
{ // ãããã¯ã¹ã³ã¼ã
{ // æ°ããªãããã¯ã¹ã³ã¼ã
}
}
é¸ææã¯ãè¤æ°ããããã¼ã®ãã¡ãã©ããã²ã¨ã¤ãé¸ã¶æã®ãã¨ã§ããã
ãããé¸ææã®ä¸ã®æããè¤åæã§ã¯ãªãã£ãå ´åããã®æãè¤åæã§å²ãã å ´åã¨åãã«ãªãã
void f( bool b )
{
if ( b )
int x ;
x = 0 ; // ã¨ã©ã¼ãxã¯å®£è¨ããã¦ããªã
}
ãã®ã³ã¼ãã¯ã以ä¸ã®ã³ã¼ãã¨åçã§ãããããifæã®æ¬¡ã®å¼æã§ãxã¨ããååãè¦ã¤ããããªãã
void f( bool b )
{
if ( b )
{ int x ; }
x = 0 ; // ã¨ã©ã¼ãxã¯å®£è¨ããã¦ããªã
}
æ¡ä»¶ã«ã¤ãã¦
æ¡ä»¶:
å¼
宣è¨
æ¡ä»¶ã«ã¯ãå¼ã宣è¨ãæ¸ããã¨ãã§ãããæ¡ä»¶ã¯ãifæãswitchæã ãã§ã¯ãªããwhileæãªã©ã§ã使ãããã
void f()
{
if ( true ) ;
if ( int x = 1 ) ;
}
æ¡ä»¶ã«å®£è¨ãæ¸ããã¨ãã§ããçç±ã¯ãã³ã¼ããåç´ã«ããããã§ããã
// ä½ãå¦çããã¦çµæãè¿ãé¢æ°
int do_something() ;
int main()
{
int result = do_something() ;
if ( result )
{
// å¦ç
}
}
æ¡ä»¶ã«ã¯å®£è¨ãæ¸ãäºãã§ããããã以ä¸ã®ããã«æ¸ããã¨ãã§ããã
if ( int result = do_something() )
if ( æ¡ä»¶ ) æ
if ( æ¡ä»¶ ) æ else æ
ifæã¯ãæ¡ä»¶ã®å¤ã«ãã£ã¦ãå®è¡ãã¹ãæãå¤ããã
æ¡ä»¶ãtrueã¨è©ä¾¡ãããå ´åãä¸ã¤ç®ã®æãå®è¡ããããæ¡ä»¶ãfalseã¨è©ä¾¡ãããå ´åãelseã«ç¶ãäºã¤ç®ã®æãæãã®ãªãã°ãäºã¤ç®ã®æãå®è¡ãããã
int main()
{
if ( true ) // ä¸ã¤ç®ã®æãå®è¡ããã
/*ä¸ã¤ç®ã®æ*/ ;
if ( false ) // ä¸ã¤ç®ã®æã¯å®è¡ãããªã
/*ä¸ã¤ç®ã®æ*/ ;
if ( true ) // ä¸ã¤ç®ã®æãå®è¡ããã
/*ä¸ã¤ç®ã®æ*/ ;
else
/*äºã¤ç®ã®æ*/ ;
if ( false ) // äºã¤ç®ã®æãå®è¡ããã
/*ä¸ã¤ç®ã®æ*/ ;
else
/*äºã¤ç®ã®æ*/ ;
}
elseã¯ãè¿ãæ¹ã®ifæã«å¯¾å¿ããã
int main()
{
if ( false ) // #1
if ( true ) ; // #2
else { } // #2ã®ifæã«å¯¾å¿ããelse
}
ã¤ã³ãã³ãã«é¨ããã¦ã¯ãããªããã¤ã³ãã³ããæ£ãã対å¿ãããã¨ã以ä¸ã®ããã«ãªãã
int main()
{
if ( false ) // #1
if ( true ) ; // #2
else ; // #2ã®ifæã«å¯¾å¿ããelse
}
ãã®ãããelseã®ããifæã®ä¸ã«ãããã«ifæããã¹ãããããå ´åã¯ãå
å´ã®ifæã«ããelseãå¿
è¦ã§ããã
int main()
{
if ( false ) // #1
if ( true ) ; // #2
else ; // #2ã®ifæã«å¯¾å¿ããelse
else ; // #1ã®ifæã«å¯¾å¿ããelse
}
ãããã¯ããããã¯æã使ãã¨ããæãããã
int main()
{
if ( false ) // #1
{ if ( true ) ; }
else ; // #1ã®ifæã«å¯¾å¿ããelse
}
switch( æ¡ä»¶ ) æ
switchæã¯ãæ¡ä»¶ã®å¤ã«ãã£ã¦ãå®è¡ããæãé¸æããã
æ¡ä»¶ã¯ãæ´æ°åãenumåããããã¯éexplicitãªå¤æé¢æ°ãæã¤ã¯ã©ã¹åã§ãªããã°ãªããªããæ¡ä»¶ãã¯ã©ã¹åã®å ´åãæ´æ°åãenumåã«åå¤æãããã
struct C
{
operator int(){ return 0 ; }
} ;
int main()
{
switch(1) ; // OK
C c ;
switch(c) ; // OKãC::operator int()ãå¼ã°ãã
switch(1.0) ; // ã¨ã©ã¼ãæµ®åå°æ°ç¹æ°åã¯æå®ã§ããªã
switch( static_cast<int>(1.0) ) ; // OK
}
switchæã®ä¸ã®æã«ã¯ãé常ãè¤åæãæå®ãããè¤åæã®ä¸ã«ã¯ãcaseã©ãã«æãdefaultã©ãã«æãæ¸ãã
switch(1)
{
case 1 :
/* å¦ç */ ;
break ;
case 2 :
/* å¦ç */ ;
break ;
default :
/* å¦ç */ ;
}
caseã©ãã«æã«æå®ããå¼ã¯ãæ´æ°ã®å®æ°å¼ã§ãªããã°ãªããªããã¾ããåãswitchå
ã§ãcaseã©ãã«æã®å¤ãéè¤ãã¦ã¯ãªããªãã
defaultã©ãã«æã¯ãswitchæã®ä¸ã®æã«ãã²ã¨ã¤ã ãæ¸ããã¨ãã§ããã
switchæãå®è¡ãããã¨ãã¾ãæ¡ä»¶ãè©ä¾¡ããããçµæã®å¤ããswitchæã®ä¸ã«ããcaseã©ãã«ã«å¯¾ãã¦ãã²ã¨ã¤ã¥ã¤æ¯è¼ãããããããå¤ãçããcaseã©ãã«æãè¦ã¤ãã£ãå ´åããã®ã©ãã«æã«å®è¡ã移ãã
void f( int const value )
{
switch( value )
{
case 1 :
std::cout << "Good morning." << std::endl ;
break ;
case 2 :
std::cout << "Good afternoon." << std::endl ;
break ;
case 3 :
std::cout << "Good evening." << std::endl ;
break ;
}
}
int main()
{
f( 1 ) ; // Good morning.
f( 2 ) ; // Good afternoon.
f( 3 ) ; // Good evening.
}
æ¡ä»¶ã¨å¤ã®çããcaseã©ãã«ãè¦ã¤ãããªãå ´åã§ãdefaultã©ãã«ãããå ´åãdefaultã©ãã«ã«å®è¡ã移ãã
void f( bool const value )
{
switch( value )
{
case true :
std::cout << "true" << std::endl ;
break ;
default :
std::cout << "false" << std::endl ;
break ;
}
}
int main()
{
f( true ) ; // true
f( false ) ; // false
}
æ¡ä»¶ã¨å¤ã®çããcaseã©ãã«ãè¦ã¤ããããdefaultã©ãã«ããªãå ´åãswitchå
ã®æã¯å®è¡ãããªãã
int main()
{
// switchå
ã®æã¯å®è¡ãããªã
switch( 0 )
{
case 999 :
std::cout << "hello" << std::endl ;
break ;
case 123456 :
std::cout << "hello" << std::endl ;
break ;
}
}
caseã©ãã«ã¨defaultã©ãã«èªä½ã«ã¯ãæã®å®è¡ãå¤æ´ããæ©è½ã¯ãªãã
void f( int const value )
{
switch( value )
{
case 1 :
std::cout << "one" << std::endl ;
default :
std::cout << "default" << std::endl ;
case 2 :
std::cout << "two" << std::endl ;
}
}
ãã®å ´åãvalueã®å¤ã1ã®å ´åãcase 1ã®ã©ãã«æã«ç¶ãæãããã¹ã¦å®è¡ããã¦ãã¾ããã¾ããvalueã®å¤ã1ã§ã2ã§ããªãå ´åãdefaultã©ãã«æã«ç¶ãcase 2ã®ã©ãã«æããå®è¡ããã¦ãã¾ãããã®ãããswitchå
ã®å®è¡ãåãä¸ãããæç¹ã§ãbreakæãæ¸ããªããã°ãªããªããbreakæãæ¸ãå¿ãããã¨ã«ãããæå³ããªãæã®å®è¡ã¯ããããããã¨ãªã®ã§ã注æãå¿
è¦ã§ããããªãããã®ãã¨ã¯ãéã«å©ç¨ãããã¨ãã§ããã
void f( int const value )
{
switch( value )
{
case 3 :
case 5 :
case 7 :
/* ä½ããã®å¦ç */ ;
}
}
ãã®ä¾ã§ã¯ãvalueã®å¤ã3, 5, 7ã®ããããã®å ´åã«ãä½ããã®å¦çãå®è¡ãããã
ç¹°ãè¿ãæï¼Iteration statementsï¼ã¯ãã«ã¼ããæ¸ãããã®æã§ããã
ç¹°ãè¿ãæã®ä¸ã®æã¯ãæé»çã«ããããã¯ã¹ã³ã¼ããå®ç¾©ããããã®ãããã¯ã¹ã³ã¼ãã¯ãæã®å®è¡ã®ã«ã¼ãä¸åãã¨ã«ãåºå
¥ããããä¾ãã°ã
while ( true )
int i ;
ã¨ããæã¯ã以ä¸ã®ããã«æ¸ãããã®ã¨ã¿ãªãããã
while ( true )
{ int i ; }
å¾ã£ã¦ãç¹°ãè¿ãæã®ä¸ã®å¤æ°ã¯ãã«ã¼ããåããããã¨ã«ãçæãç ´æ£ããããã¨ã«ãªãã
struct C
{
C(){ std::cout << "constructed." << std::endl ; }
~C(){ std::cout << "destructed." << std::endl ; }
} ;
int main()
{
while ( true )
{ // çæãç ´æ£ãç¹°ãè¿ã
C c ;
}
}
while ( æ¡ä»¶ ) æ
whileæã¯ãæ¡ä»¶ã®çµæãfalseã«ãªãã¾ã§ãæãç¹°ãè¿ãå®è¡ãããæ¡ä»¶ã¯ãæã®å®è¡åã«ãç¹°ãè¿ãè©ä¾¡ãããã
int main()
{
// ä¸åº¦ãç¹°ãè¿ããªã
while ( false )
{
std::cout << "hello" << std::endl ;
}
// ç¡éã«ã¼ã
while ( true )
{
std::cout << "hello" << std::endl ;
}
// iã10ã«ãªãã¾ã§ç¹°ãè¿ã
int i = 0 ;
while ( i != 10 )
{
++i ;
}
}
æ¡ä»¶ã宣è¨ã§ããå ´åãå¤æ°ã®ã¹ã³ã¼ãã¯ãwhileæã®å®£è¨ãããå ´æãããwhileæã®æå¾ã¾ã§ã§ãããæ¡ä»¶ã®ä¸ã§å®£è¨ãããå¤æ°ã¯ãæã®å®è¡ãç¹°ãè¿ããããã³ã«ãçæãç ´æ£ãããã
while ( T t = x ) æ
ã¨ããæã¯ã
label:
{
T t = x;
if (t)
{
æ
goto label;
}
}
ã¨æ¸ãã®ã«çããã
whileæã®æ¡ä»¶ã®ä¸ã§å®£è¨ãããå¤æ°ã¯ãã«ã¼ãã®ç¹°ãè¿ãã®ãã³ã«ãç ´æ£ããã¦ããåã³çæãããã
#include <iostream>
class nonzero
{
private :
int value ;
public :
nonzero( int i )
: value(i)
{ std::cout << "constructed" << std::endl ; }
~nonzero()
{ std::cout << "destructed" << std::endl ;}
operator bool() { return value != 0 ; }
} ;
int main()
{
int i = 3 ;
while ( nonzero n = i )
{
--i ;
}
}
do æ while ( å¼ ) ;
doæã®å¼ã¯ãboolã«å¤æããããboolã«å¤æã§ããªãå ´åãã¨ã©ã¼ã¨ãªãã
doæã¯ãå¼ã®çµæãfalseã«ãªãã¾ã§ãæãç¹°ãè¿ãå®è¡ãããããã ããå¼ã®è©ä¾¡ã¯ãæã®å®è¡ã®å¾ã«è¡ãããã
int main()
{
// ä¸åº¦ã ãæãå®è¡
do {
std::cout << "hello" << std::endl ;
} while ( false ) ;
// ç¡éã«ã¼ã
do {
std::cout << "hello" << std::endl ;
} while ( true ) ;
}
for ( foråæåæ æ¡ä»¶opt ; å¼opt ) æ
foråæåæ:
å¼æ
宣è¨
foræã¯ãforåæåæã§ãã«ã¼ãåã®åæåãæ¸ããæ¡ä»¶ã§ãã«ã¼ããå®è¡ãããã©ããã®å¤å®ãè¡ããæãå®è¡ããããã¨ã«ããã®ã¤ã©å¼ãè©ä¾¡ãããã
foræã®å®è¡ã§ã¯ãã¾ããforåæåæãå®è¡ããããforåæåæã¯ãå¼æããå¤æ°ã®å®£è¨ãè¡ããã¨ãã§ãããå¤æ°ã®ã¹ã³ã¼ãã¯ãforæã®æå¾ã¾ã§ã§ããã次ã«ãæã®å®è¡ã®åã«ãæ¡ä»¶ãè©ä¾¡ãããfalseã¨ãªãã¾ã§æãç¹°ãè¿ãå®è¡ããããæã®å®è¡ã®å¾ã«ãå¼ãè©ä¾¡ãããã
for ( foråæåæ æ¡ä»¶ ; å¼ ) æ
ã¯ã以ä¸ã®ã³ã¼ãã¨åçã§ããã
{
foråæåæ
while ( æ¡ä»¶ )
{
æ
å¼ ;
}
}
ãã ããæã®ä¸ã§continueæã使ã£ãã¨ãã¦ããå¼ã¯è©ä¾¡ãããã¨ããéããããã
foræã¯ãwhileæã§ããæ¸ãããã³ã¼ããæ¸ããããããæ§æã§ãããä¾ãã°ãwhileæã10åå®è¡ãããå ´åã
int main()
{
// ã«ã¦ã³ã¿ã¼ç¨ã®å¤æ°ã®å®£è¨
int i = 0 ;
while ( i != 10 )
{
// å¦ç
++i ;
}
}
ãã®ãããªã³ã¼ããæ¸ããforæã¯ããã®ãããªã³ã¼ãããä¸åº¦ã«æ¸ããããã«ãããã®ã§ããã
int main()
{
for ( int i = 0 ; i != 10 ; ++i )
{
// å¦ç
}
}
foræã®æ¡ä»¶ã¨å¼ã¯ãçç¥ãããã¨ãã§ãããæ¡ä»¶ãçç¥ããå ´åãtrueã¨ã¿ãªãããã
int main()
{
// æ¡ä»¶ãçç¥ãfor ( ; true ; ) ã¨åã
for ( ; ; ) ;
}
ããã§ã¯ãrange-based forã®è¨èªæ©è½ã説æãã¦ãããã©ã¤ãã©ãªã¨ãã¦ã®ã¬ã³ã¸ããã¦ã¼ã¶ã¼å®ç¾©ã®ã¯ã©ã¹ã§ã¬ã³ã¸ããµãã¼ãããæ¹æ³ã«ã¤ãã¦ã¯ãã©ã¤ãã©ãªã®ã¬ã³ã¸ãåç
§ã
for ( for-range-å®£è¨ : for-range-åæåå ) æ
range-based forã¯ãã¬ã³ã¸ããµãã¼ããã¦ããé
åãåæåãªã¹ããã¯ã©ã¹ã®åè¦ç´ ã«å¯¾ãã¦ãããããæãå®è¡ããããã®æã§ããã
range-based forã¯ãforã«ç¶ãã¦ãæ¬å¼§ãæ¸ããæ¬å¼§ã®ä¸ã«ã¯ãå¤æ°ã®å®£è¨ã¨ãã¬ã³ã¸ã¨ãã:ã§åºåãã
int main()
{
int a[] = { 1, 2, 3 } ;
for ( int i : a ) ; // åè¦ç´ ãintåã®ã³ãã¼ã§åãã
for ( int & ref : a ) ; // åè¦ç´ ããªãã¡ã¬ã³ã¹ã§åãã
for ( auto i : a ) ; // autoæå®åã使ã£ãä¾
}
ãã®ããã«ãã¦å®£è¨ããå¤æ°ã¯ãrange-based foræã®ä¸ã§ä½¿ããã¨ãã§ãããrange-based foræã¯ãå¤æ°ãã¬ã³ã¸ã®åè¦ç´ ã§åæåããã
int main()
{
int a[] = { 1, 2, 3 } ;
for ( auto i : a )
{
i ;
}
}
ãã®ä¾ã§ã¯ãã«ã¼ãã¯3åå®è¡ãããå¤æ°iã®å¤ã¯ãããããã1, 2, 3ã¨ãªãã
ã«ã¼ãã使ã£ã¦ã³ã¼ããæ¸ãå ´åãé
åãã³ã³ããã¼ã®åè¦ç´ ã«å¯¾ãã¦ãããããä½ããã®å¦çãããã¨ããäºãå¤ãã
#include <iostream>
int main()
{
int a[5] = { 1, 2, 3, 4, 5 } ;
for (
int * iter = &a ; // åè¦ç´ ã表ãå¤æ°ã®å®£è¨
iter != &a + 5 ; // çµäºæ¡ä»¶ã®å¤å®
++iter // 次ã®è¦ç´ ã®åç
§
)
{
// åè¦ç´ ã«å¯¾ããå¦ç
std::cout << *iter << std::endl ;
}
}
ãããããã®ãããªã«ã¼ããæ£ããæ¸ãã®ã¯ãè³é£ã®æ¥ã§ããããªããªãã°ã人éã¯ééããç¯ãããã§ããããããããã®ãããªã«ã¼ãã¯ã誰ãæ¸ãã¦ããæ¦ãä¼¼ããããªã³ã¼ãã«ãªããrange-based forã使ãã°ããã®ãããªåé·ãªã³ã¼ããçããã¨ãã§ããã
int main()
{
int a[5] = { 1, 2, 3, 4, 5 } ;
for ( auto i : a )
{
std::cout << i << std::endl ;
}
}
range-based forã¯ã極ãã¦ç°¡åã«ä½¿ããã¨ãã§ãããfor-range-宣è¨ã§ãåè¦ç´ ãå¾ãããã®å¤æ°ã宣è¨ãããfor-rangeåæååã§ãã¬ã³ã¸ããµãã¼ãããå¼ãæ¸ããæã§ãåè¦ç´ ã«å¯¾ããå¦çãæ¸ãã
int main()
{
int a[5] = { 1, 2, 3, 4, 5 } ;
for ( int & i : a )
{
i *= 2 ; // äºåãã
}
}
ãã®ä¾ã§ã¯ãé
åaã®åè¦ç´ ã¯ãäºåããããé
åã®è¦ç´ ãæ¸ãæããããã«ãå¤æ°ã¯åç
§ã§åãã¦ããã
range-based forã«ã¯ãé
åã®ä»ã«ããåæåãªã¹ãããã¬ã³ã¸ããµãã¼ãããã¯ã©ã¹ãæ¸ãäºãã§ãããSTLã®ã³ã³ããã¼ã¯ãã¬ã³ã¸ããµãã¼ããã¦ãããé
å以å¤ã«range-based forãé©ç¨ããå ´åã<iterator>ã®#includeãå¿
è¦ã§ããã
#include <iterator>
int main()
{
// é
å
int a[] = { 1, 2, 3 } ;
for ( auto i : a )
{ std::cout << i << std::endl ; }
// åæåãªã¹ã
for ( auto i : { 1, 2, 3 } )
{ std::cout << i << std::endl ; }
// ã¯ã©ã¹
std::vector<int> v = { 1, 2, 3 } ;
for ( auto i : v )
{ std::cout << i << std::endl ; }
}
range-based forã¯ãæ¬æ¥ãã³ã³ã»ããã¨ããè¨èªæ©è½ã¨å
±ã«æä¾ãããäºå®ã§ãã£ããããããã³ã³ã»ããã¯ç´ä½æ²æãçµãçµæãC++11ã§ã¯å´ä¸ãããããã®ãããç¾è¡ã®range-based forã¯ãã³ã³ã»ããã§ã¯ãªããADLã«ããå®è£
ãããã¦ããã
以ä¸ã®range-based foræãããã¨ããã
for ( for-range-å®£è¨ : for-range-åæåå ) æ
ãã®range-based foræã¯ã以ä¸ã®ããã«å¤æãããã
for-range-åæååãå¼ã®å ´åãæ¬å¼§ã§ããããããããã¯ãã³ã³ãå¼ã渡ãããã¨ãã«ãæ£ããå¼ãè©ä¾¡ããããã§ããã
for ( auto i : a, b, c, d ) ;
// æ¬å¼§ã§ããã
for ( auto i : (a, b, c, d) ) ;
for-range-åæååãåæåãªã¹ãã®å ´åããªã«ãããªãã
{
// å¼ã®çµæãlvalueãrvalueã®ãªãã¡ã¬ã³ã¹ã§æç¸
auto && __range = for-range-åæåå ;
for (
auto __begin = beginå¼, // å
é ã®ã¤ãã¬ã¼ã¿ã¼
__end = endå¼ ; // çµç«¯ã®ã¤ãã¬ã¼ã¿ã¼
__begin != __end ; // çµäºæ¡ä»¶
++__begin ) // ã¤ãã¬ã¼ã¿ã¼ã®ã¤ã³ã¯ãªã¡ã³ã
{
for-range-å®£è¨ = *__begin; // è¦ç´ ãå¾ã
æ
}
}
ããã§ã®ã__rangeã__beginã__endã¨ããå¤æ°ã¯ã説æã®ããã®ä»®ã®ååã§ãããå®éã®range-based foræã®ä¸ã§ã¯ããã®ãããªå¤æ°åã¯åå¨ããªãã
__rangeã¨ã¯ãfor-range-åæååã®å¼ã®çµæãä¿æããããã®ãªãã¡ã¬ã³ã¹ã§ãããautoæå®åã¨rvalueãªãã¡ã¬ã³ã¹ã®å®£è¨åã使ããã¦ãããã¨ã«ãããå¼ã®lvalueãrvalueãCV修飾åãããããåããã«ãçµæããªãã¡ã¬ã³ã¹ã¨ãã¦æç¸ã§ããã
beginå¼ã¨endå¼ã¯ãå
é ã¨çµç«¯ã¸ã®ã¤ãã¬ã¼ã¿ã¼ãå¾ãããã®å¼ã§ããã
for-range-åæååã®åããé
åã®å ´åãbeginå¼ã¯ã__rangeãã¨ãªããendå¼ã¯ãã__range + é
åã®è¦ç´ æ°ãã¨ãªãã
int x [10] ;
for ( auto i : x )
{
// å¦ç
}
ä¸è¨ã®range-based foræã¯ã以ä¸ã®ããã«å¤æãããã
int x [10] ;
{
auto && __range = ( x ) ;
for (
auto __begin = __range,
__end = __range + 10 ;
__begin != __end ;
++__begin )
{
auto i = *__begin;
// å¦ç
}
}
åãé
å以å¤ã®å ´åãbeginå¼ã¯ãbegin(__range)ãã«ãendå¼ã¯ãend(__range)ãã«å¤æãããã
std::vector<int> v ;
for ( auto i : v )
{
// å¦ç
}
std::vector<int> v ;
{
// å¼ã®çµæãlvalueãrvalueã®ãªãã¡ã¬ã³ã¹ã§æç¸
auto && __range = ( v ) ;
for (
auto __begin = begin(__range),
__end = end(__range) ;
__begin != __end ;
++__begin )
{
auto i = *__begin;
// å¦ç
}
}
ããã§ã®begin(__range)ã¨end(__range)ã¯ãé¢æ°å¼ã³åºãã§ããããã ãããã®ååã®è§£æ±ºã«ã¯ãé常ã®ååæ¢ç´¢ã®ã«ã¼ã«ã¯ç¨ããããªããbegin/endã®ååæ¢ç´¢ã«ã¯ãé¢é£åå空éã«ç¹å¥ã«stdãå ãããADLã«ãã£ã¦ã®ã¿ååæ¢ç´¢ããããé常ã®unqualifiedååæ¢ç´¢ã¯ç¨ããããªããADLã®è©³ç´°ã«ã¤ãã¦ã¯ã詳ãã説æãå¥ã«è¨ãã¦ããã®ã§ããã¡ããåç
§ã
ã¸ã£ã³ãæã¯ãå®è¡ããæãç¡æ¡ä»¶ã§å¤æ´ããããã®æã§ããã
break ;
breakæã¯ãç¹°ãè¿ãæãswitchæã®ä¸ã§ä½¿ããã¨ãã§ãããbreakæã¯ãæãå
å´ã®ç¹°ãè¿ãæãswitchæãããæãåºãæ©è½ãæã¤ãããç¹°ãè¿ãæãswitchæã«ç¶ãã次ã®æãããã°ãå®è¡ã¯ãã®æã«ç§»ããbreakæã¯ãã«ã¼ããéä¸ã§æãããå ´åã«ä½¿ããã¨ãã§ããã
int main()
{
while ( true )
{
break ;
}
do
{
break ;
} while ( true ) ;
for ( ; ; )
{
break ;
}
switch(0)
{
default :
break ;
}
}
breakæã«ãã£ã¦æããç¹°ãè¿ãæãswitchæã¨ã¯ãbreakæãæ¸ããã¦ããå ´æããã¿ã¦ãæãå
å´ã®æã§ããã
int main()
{
while ( true ) // å¤å´
while ( true ) // å
å´
{
break ;
}
}
breakæã使ããã¦ããå
å´ã®æããã¯æããããå¤å´ã®æããæãããã¨ã¯ã§ããªãã
continue ;
continueæã¯ãç¹°ãè¿ãæã®ä¸ã§ä½¿ããã¨ãã§ãããcontinueæãå®è¡ããã¨ããã®ã«ã¼ãã®å®è¡ãä¸æ¢ããã
whileæãdoæã®å ´åãæ¡ä»¶ãè©ä¾¡ããããã®çµæ次第ã§ã次ã®ã«ã¼ããåã³å§ã¾ããforæã®å ´åã¯ãã«ã¼ãã®æå¾ã«å¿
ãè¡ãããå¼ããããããã°è©ä¾¡ãããæ¡ä»¶ãè©ä¾¡ããããã®çµæ次第ã§ã次ã®ã«ã¼ããåã³å§ã¾ãã
int main()
{
while ( true )
{
continue ;
}
do
{
continue ;
} while ( true ) ;
for ( int i = 0 ; true ; ++i )
{
continue ; // foræã®å¼ã§ãã++iãè©ä¾¡ãããã
}
}
continueæã«å¯¾ããç¹°ãè¿ãæã¨ã¯ãcontinueæãæ¸ããã¦ããå ´æããã¿ã¦ãæãå
å´ã®ç¹°ãè¿ãæã®ã«ã¼ãã§ããã
int main()
{
while ( true ) // å¤å´
while ( true ) // å
å´
{
continue ;
}
}
ãã®ä¾ã§ã¯ãcontinueæã¯ãå
å´ã®whileæã®ã«ã¼ããä¸æ¢ããããã ããcontinueæã¯breakæã¨ã¯éããç¹°ãè¿ãæããæãåºãããã§ã¯ãªãã®ã§ãå
å´ã®whileæã®å®è¡ãç¶ãã
return å¼opt ;
return åæåãªã¹ã ;
returnæã¯ãé¢æ°ã®å¼ã³åºãå
ã«å®è¡ãæ»ãæã§ããã
int f()
{
return 0 ; // OK
return ; // ã¨ã©ã¼ãæ»ãå¤ããªã
}
returnæã®å¼ã¯ãé¢æ°ã®å¼ã³åºãå
ã«ãæ»ãå¤ã¨ãã¦è¿ããããå¼ã¯é¢æ°ã®æ»ãå¤ã®åã«æé»çã«å¤æããããå¤æã§ããªãå ´åã¯ã¨ã©ã¼ã¨ãªãã
æ»ãå¤ãè¿ããªãé¢æ°ã®å ´åãreturnæã®å¼ã¯çç¥ã§ãããæ»ãå¤ãè¿ããªãé¢æ°ã¨ã¯ãæ»ãå¤ã®åãvoidåã®é¢æ°ãã³ã³ã¹ãã©ã¯ã¿ã¼ããã¹ãã©ã¯ã¿ã¼ã§ããã
struct C
{
C() { return ; }
~C() { return ; }
} ;
void f() { return ; }
æ»ãå¤ãè¿ããªãé¢æ°ã®å ´åã¯ãreturnæã§æ»ãå¤ãè¿ãã¦ã¯ãªããªãã
void f()
{
return ; // OK
return 0 ; // ã¨ã©ã¼ãé¢æ°fã¯æ»ãå¤ãè¿ããªã
}
ãã ããreturnæã®å¼ãvoidã¨è©ä¾¡ãããå ´åã¯ãæ»ãå¤ãè¿ãã¦ãããã¨ã«ã¯ãªããªãã
void f() { }
void g()
{
// é¢æ°fã®å¼ã³åºãã®çµæã¯ãvoid
return f() ;
}
é¢æ°ã®æ¬ä½ã®æå¾ã¯ãå¤ãè¿ããªãreturnæãæ¸ããããã¨ã«ãªãã
void f()
{
// å¤ãè¿ããªãreturnæãæ¸ãããå ´åã¨åã
}
å¤ãè¿ãé¢æ°ã§ãreturnæãçç¥ãããå ´åã®æåã¯æªå®ç¾©ã§ããããã ããmainé¢æ°ã ãã¯ãç¹å¥ã«0ãè¿ããããã®ã¨ã¿ãªãããã
// å¤ãè¿ãé¢æ°
int f( bool b )
{
if ( b )
{ return 0 ; }
// bãfalseã®å ´åã®æåã¯æªå®ç¾©
}
int main()
{
// return 0 ;ãæ¸ãããå ´åã¨åã
}
returnæã«ã¯ãåæåãªã¹ããæ¸ããã¨ãã§ããã
std::initializer_list<int> f()
{
return { 1, 2, 3 } ;
}
struct List
{
List( std::initializer_list<int> ) { }
} ;
List g()
{
return { 1, 2, 3 } ;
}
returnæã¯ãé¢æ°ã®æ»ãå¤ã®çºã«ãä¸æãªãã¸ã§ã¯ããçæãããããããªããä¸æãªãã¸ã§ã¯ããçæããå ´åãå¤ã¯ã³ãã¼ãã ã¼ããããªããã°ãªããªãããreturnæã§ã¯ãã³ãã¼ãã ã¼ããã®é¸æã®ããã«ãå¼ãrvalueã¨ã¿ãªãå¯è½æ§ããããå¼ãrvalueã¨ã¿ãªãã¨ãããã¨ã¯ãlvalueã§ãã£ã¦ããæé»çã«ã ã¼ããããå¯è½æ§ããããã¨ãæå³ãããããã¯ä¾ãã°ããreturnæãå®è¡ãã¦é¢æ°ã®å¼ã³åºãå
ã«æ»ã£ãå ´åãé¢æ°ã®ãã¼ã«ã«å¤æ°ã¯ç ´æ£ãããããã ã¼ããã¦ããã¾ããªããã¨ããç¶æ³ã§ãã³ãã¼ã§ã¯ãªããã ã¼ããé¸æã§ããããã«ããããã§ããã
// ã³ãã¼ã¨ã ã¼ããå¯è½ãªã¯ã©ã¹
struct C
{
C() = default ; // ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼
C( C const & ) = default ; // ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼
C( C && ) = default ; // ã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼
} ;
C f()
{
C c ;
// ä¸æãªãã¸ã§ã¯ããçæãããå ´åãã³ãã¼ãã ã¼ããè¡ãããã
return c ;
// ãªããªãã°ããã¼ã«ã«å¤æ°ã¯returnæã®å®è¡å¾ãç ´æ£ãããã®ã§ãã ã¼ããã¦ãæ§ããªãããã§ããã
}
ã¾ããä¸è¨ã®ã³ã¼ãã§ãä¸æãªãã¸ã§ã¯ããçæãããªãå ´åããããããã¯ã¤ã³ã©ã¤ã³å±éãããã¼è§£æãªã©ã«ããæé©åã®çµæãã³ãã¼ãã ã¼ããè¡ããªãã¦ãããã¨å¤æã§ããå ´åããã®ãããªæé©åã許å¯ããããã§ããã
goto èå¥å ;
gotoæã¯ãé¢æ°å
ã®ã©ãã«æã«ç¡æ¡ä»¶ã§å®è¡ã移ãããã®æã§ãããåãé¢æ°å
ã§ããã°ãã©ãã«ã§ãã¸ã£ã³ãã§ããã
int main()
{
label : ; // labelã¨ããååã®ã©ãã«æ
goto label ;
}
宣è¨æã®åã«ã¸ã£ã³ãããããããã¯ã宣è¨æãé£ã³è¶ããã¨ã«ã¤ãã¦ã¯ã宣è¨æã®é
ç®ã§è©³ãã解説ãã¦ããã
ãããã¯å®£è¨ ;
宣è¨æã¯ããããããã¯ã®ä¸ã«ãæ°ããèå¥åãå°å
¥ããããã®æã§ããããããã¯å®£è¨ãããã®ä»ã®å®£è¨ã«ã¤ãã¦ã®è©³ç´°ã¯ã宣è¨ã宣è¨åãã¯ã©ã¹ãåç
§ã
int main()
{
int a ; // intåã®èå¥åaã¨ããå¤æ°ã®å®£è¨
void f(void) ; // void (void)åã®èå¥åfã¨ããé¢æ°ã®å®£è¨
}
èªåã¹ãã¬ã¼ã¸ã®æå¹æéãæã¤å¤æ°ã¯ã宣è¨æãå®è¡ããããã³ã«ãåæåããããã¾ãã宣è¨ããã¦ãããããã¯ããæããéã«ãç ´æ£ãããã
struct Object
{
Object()
{ std::cout << "constructed." << std::endl ; }
~Object()
{ std::cout << "destructed." << std::endl ; }
} ;
int main()
{
{
Object object ; // çæ
} // ãããã¯ã¹ã³ã¼ãããæããéã«ç ´æ£ããã
}
ã¸ã£ã³ãæã使ãã°ã宣è¨æã®å¾ããåã«å®è¡ã移ããã¨ãå¯è½ã§ããããã®å ´åã宣è¨æã«ãã£ã¦çæããããªãã¸ã§ã¯ãã¯ç ´æ£ããã宣è¨æã®å®è¡ã¨å
±ã«ãåã³çæãåæåãããã
struct Object
{
Object()
{ std::cout << "constructed." << std::endl ; }
~Object()
{ std::cout << "destructed." << std::endl ; }
} ;
int main()
{
label :
Object object ; // å¤æ°objectãçæãåæåããã
goto label ; // å¤æ°objectã¯ç ´æ£ããã
}
ãã®ä¾ã§ã¯ãObjectã¯ã©ã¹ã®å¤æ°objectã¯ãgotoã§å®£è¨æã®åã«ã¸ã£ã³ããããã³ã«ãç ´æ£ããããã¨ã«ãªãã
gotoæãswitchæãªã©ã®ã¸ã£ã³ãæã使ãã°ãèªåå¤æ°ã®å®£è¨æãå®è¡ããã«ãéãè¶ãã³ã¼ããæ¸ããã
// gotoæã®ä¾
void f()
{
// labelã¨ããååã®ã©ãã«æã«ã¸ã£ã³ããã
goto label ;
int value ; // èªåå¤æ°ã®å®£è¨æ
label : ;
// valueã®å®£è¨æããå®è¡ããã«éãè¶ãã¦ãã¾ã£ãã
}
// switchæã®ä¾
void g( int value )
{
switch ( value )
{
int value ; // å¤æ°ã®å®£è¨æ
// 宣è¨æãé£ã³è¶ãã¦ãã¾ã£ã¦ããã
case 0 : break ;
case 1 : break ;
default : break ;
}
}
ãã®ãããªã³ã¼ãã¯ãã»ã¼ãã¹ã¦ã®å ´åãã¨ã©ã¼ã¨ãªãã®ã§ãæ¸ãã¹ãã§ã¯ãªããã§ã¯ãå¤æ°ã®å®£è¨æãéãè¶ãã¦ãã¨ã©ã¼ã¨ãªããªãå ´åã¯ä½ããããã¯ãç¸å½ã®å¶éãåãããã¾ããå¤æ°ã®åã¯ãã¹ã«ã©ã¼åããtrivialãªããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¨trivialãªãã¹ãã©ã¯ã¿ã¼ãæã¤ã¯ã©ã¹åã§ãªããã°ãªããªããã¾ãããã®ãããªåã«CV修飾åãå ããåã¨ãé
ååã§ãããããã®ä¸ã§ãåæååãåå¨ãã¦ãã¦ã¯ãªããªãã
struct POD { } ;
// trivialã§ã¯ãªãã³ã³ã¹ãã©ã¯ã¿ã¼ãæã¤ã¯ã©ã¹
struct Object { Object() {} } ;
int main()
{
// å¤æ°ã®å®£è¨æãé£ã³è¶ããgotoæ
goto label ;
// ã¨ã©ã¼
// å¤æ°ã®åã¯ã¹ã«ã©ã¼åã ããåæååãããã
int value = 0;
int scalar ; // OK
// ã¨ã©ã¼
// å¤æ°ã®ã¯ã©ã¹åãtrivialã§ã¯ãªãã³ã³ã¹ãã©ã¯ã¿ã¼ãæã£ã¦ãã
Object object ;
POD pod ; // OK
label : ;
}
ãã¹ã¦ã®staticå¤æ°ã¨thread_localå¤æ°ã¯ãä»ã®ããããåæåã«å
ç«ã£ã¦ãã¼ãåæåãããã
int main()
{
goto label ;
static int value ; // staticå¤æ°ã¯å¿
ãã¼ãåæåããã
label :
// ãã®å ´åãvalueã¯0ã§ãããã¨ãä¿è¨¼ããã¦ãã
if ( value == 0 ) ;
}
ãããã¯ã¹ã³ã¼ãå
ã®staticå¤æ°ã¨thread_localå¤æ°ã¯ãå®æ°åæåã«ããæ©æã®åæåãè¡ãããªãå ´åã宣è¨ã«å§ãã¦å¦çãå°éããéã«ãåæåãããã
// å®æ°åæåã§ããªãå
struct X
{
int member ;
X( int value ) : member( value ) { }
} ;
void f()
{
// xã®ã¼ãåæåã¯ãã§ã«è¡ããã¦ãã
static X x(123) ;
// ãã®æç¹ã§ãxã®åæåã¯å®äºãã¦ããã
}
ãããã¯ã¹ã³ã¼ãå
ã®staticå¤æ°ã¨thread_localå¤æ°ãå®æ°åæåããã¦ããå ´åãå®è£
ã¯æ©æã«åæåãè¡ãªã£ã¦ããã¾ããªãããã ããè¡ãããã¨ããä¿è¨¼ã¯ãªãã
// å®æ°åæåã§ããå
struct X
{
int member ;
constexpr X( int value ) : member(value) { }
} ;
// å®æ°åæåã§ããªãå
struct Y
{
int member ;
Y( int value ) : member(value) { }
} ;
int g()
{
goto label ; // 宣è¨æãé£ã³è¶ãã¦ãã¾ã£ã¦ããã
// constexpræå®åã使ããã¦ããªããã¨ã«æ³¨æ
// xã¯staticå¤æ°ã§ãããconstexprã³ã³ã¹ãã©ã¯ã¿ã¼ã使ã£ã¦ãããããå®æ°åæåã§ãã
static X x( 123 ) ;
// constexprã³ã³ã¹ãã©ã¯ã¿ã¼ã使ã£ã¦ããªããããå®æ°åæåã§ã¯ãªã
static Y y( 123 ) ;
label :
// xã¯åæåããã¦ãããããããªãããåæåããã¦ããªããããããªã
// yã¯åæåããã¦ããªã
// 両æ¹ã¨ããã¼ãåæåã¯ä¿è¨¼ããã¦ãã
}
ãã®ä¾ã§ã¯ãé¢æ°gã®staticãã¼ã«ã«å¤æ°xã¨yã®å®£è¨æã«ã¯ãå¦çãå°éããªãããã®ãããxã¨yãåæåããã¦ããä¿è¨¼ã¯ãªãããã ããxã¯å®æ°åæåãªã®ã§ãå®è£
ã«ãã£ã¦ã¯ãæ©æåæåããã¦ããå¯è½æ§ããããã¼ãåæåã ãã¯å¸¸ã«ä¿è¨¼ããã¦ããã
staticå¤æ°ã¨thread_localå¤æ°ã¯ã宣è¨æã®å®è¡ã®ãã³ã«åæåããããã¨ã¯ãªãã
int f( int x )
{
// ä¸åã ãåæåããã
// å®æ°åæåãªã®ã§ããã¤åæåããããã¯å®ãããã¦ããªã
// ãã ããã¼ãåæåã¯ãã§ã«è¡ããã¦ãã
static int value = 1 ;
// ãã®æç¹ã§ãåæåã¯å®äºãã¦ãããã¨ãä¿è¨¼ããã¦ãã
int temp = value ;
value = x ;
return temp ;
}
int main()
{
f(2) ; // 1
f(3) ; // 2
f(4) ; // 3
}
ãããstaticå¤æ°ã¨thread_localå¤æ°ã®åæåããä¾å¤ãthrowããããã¨ã«ããçµäºããå ´åã¯ãåæåã¯æªå®äºã ã¨ã¿ãªãããããã®ãããªå ´åã次ã«å®£è¨æãå®è¡ããéã«ãåã³åæåã試ã¿ãããã
int flag = 0 ;
struct X
{
X()
{
if ( flag++ == 0 )
throw 0 ;
}
} ;
void f()
{
static X x ;
}
int main()
{
try
{
f() ; // é¢æ°fã®staticãã¼ã«ã«å¤æ°xã®åæåã¯æªå®äº
}
catch ( ... ) { }
f() ; // é¢æ°fã®staticãã¼ã«ã«å¤æ°xã®åæåå®äº
}
ãããstaticå¤æ°ã¨thread_localå¤æ°ã®å®£è¨æã®åæåãå帰ããå ´åãæåã¯æªå®ç¾©ã§ããã
int f( int i )
{
static int s = f(2*i); // ã¨ã©ã¼ãåæåãå帰ãã¦ãã
return i+1;
}
ãã®ä¾ã§ã¯ãstaticå¤æ°sã®åæåãçµãããªããã°ãé¢æ°fã¯returnæãå®è¡ã§ããªããããããsã®åæåã¯ãå帰ãã¦ããããã®å ´åãæåã¯æªå®ç¾©ã§ããã
é¢æ°å½¢å¼ã®ãã£ã¹ããç¨ããå¼æã¨ã宣è¨æã¨ã¯ãææ³ãææ§ã«ãªãå ´åãããããã®å ´åã宣è¨æã ã¨è§£éãããã
int main()
{
int x = 0 ;
// ä¸å¿
è¦ãªæ¬å¼§ãã¤ãã宣è¨æï¼ãããã¨ããã£ã¹ãï¼
int(x) ;
}
ãã®å ´åãint(x) ;ã¨ããæã¯ããã£ã¹ããå«ãå¼æã§ã¯ãªãã宣è¨æã«ãªãããããã£ã¦ãä¸è¨ã®ä¾ã¯ãå¤æ°xã®åå®ç¾©ã¨ãªãã®ã§ãã¨ã©ã¼ã§ããã
宣è¨ï¼declarationï¼ã¨ã¯ãååãã©ã®ããã«è§£éãããããæå®ããããã®ææ³ã§ããã
宣è¨ã«ã¯ããããã¯å®£è¨ï¼block-declarationï¼ãé¢æ°å®ç¾©ï¼function-definitionï¼ããã³ãã¬ã¼ã宣è¨ï¼template-declarationï¼ãæ示çã¤ã³ã¹ã¿ã³ã¹åï¼explicit-instantiationï¼ãæ示çç¹æ®åï¼explicit-specializationï¼ããªã³ã±ã¼ã¸æå®ï¼linkage-specificationï¼ãåå空éå®ç¾©ï¼namespace-definitionï¼ã空宣è¨ï¼empty-declarationï¼ãã¢ããªãã¥ã¼ã宣è¨ï¼attribute-declarationï¼ãããã
ãããã¯å®£è¨ã«ã¯ãåç´å®£è¨ï¼simple-declarationï¼ãåå空éã¨ã¤ãªã¢ã¹å®ç¾©ï¼namespace-alias-definitionï¼ãusing宣è¨ï¼using-declarationï¼ãusingãã£ã¬ã¯ãã£ãï¼using-directiveï¼ãstatic_assert宣è¨ï¼static_assert-declarationï¼ãã¨ã¤ãªã¢ã¹å®£è¨ï¼alias-declarationï¼ãopaque-enum宣è¨ï¼opaque-enum-declarationï¼ãããã
åç´å®£è¨ï¼simple-declarationï¼ã¯ã大ããåãã¦ä¸ã¤ã«åå²ã§ããã
ã¢ããªãã¥ã¼ãæå®å æå®å 宣è¨å ;
å¤æ°ãé¢æ°ã®å®£è¨ãªã©ã¯ããã®åç´å®£è¨ã§æ¸ããããã¨ã«ãªãã
åç´å®£è¨ã®ã¢ããªãã¥ã¼ãæå®åã¯ã宣è¨åã®ã¨ã³ãã£ãã£ã«å±ããã詳ããã¯ãã¢ããªãã¥ã¼ããåç
§ã
æå®åã¨ããã®ã¯ãintãclass Cãtypedefãªã©ãæããæå®åã¯è¤æ°æå®ã§ããã
宣è¨åã¯ãå¤æ°ãé¢æ°ãåãªã©ããã²ã¨ã¤å®£è¨ããã宣è¨åãè¤æ°æå®ã§ããã
// intåã®å¤æ°xã®å®£è¨
int // æå®å
x // 宣è¨å
;
// int const * conståã®å¤æ°pã®å®£è¨
const int // æå®å
* const p // 宣è¨å
;
// typeã¨ããååã®intåã宣è¨ã
typedef int // æå®å
type // 宣è¨å
;
宣è¨åãè¤æ°æå®ã§ãããã¨ã«ã¯ã注æãå¿
è¦ã§ãããä¾ãã°ãã²ã¨ã¤ã®å®£è¨æã§ãè¤æ°ã®å¤æ°ã宣è¨ãããã¨ãã§ããã
// intåã§ãããããa, b, c, dã¨ããååã®å¤æ°ã宣è¨
// 宣è¨åã¯4å
int a, b, c, d ;
ããã¯ãæ¯è¼çåãããããããããããã¤ã³ã¿ã¼ãé
åãé¢æ°ãªã©ã¨ããåã¯ã宣è¨åã§æå®ããã®ã§ãã²ã¨ã¤ã®å®£è¨æã§ãè¤æ°ã®å®£è¨åã使ãã¨ãããã¨ã¯ãé常ã«èªã¿ã«ããã³ã¼ããæ¸ãäºãã§ãã¦ãã¾ãã®ã§ããã
int * a, b, c[5], (*d)(void) ;
ãã®æã¯é常ã«åããã«ããããã®æãç´°ããåºåã£ã¦è§£èª¬ããã¨ã以ä¸ã®ããã«ãªãã
int // æå®å
* a, // int *åã®å¤æ°
b, // intåã®å¤æ°
c[5], // int [5]åã®å¤æ°
(*d)(void) // int(*)(void)åã®å¤æ°ãå¼æ°ãåããintåã®æ»ãå¤ãè¿ãé¢æ°ãã¤ã³ã¿ã¼
;
ã²ã¨ã¤ã®å®£è¨æã§è¤æ°ã®å®£è¨åãæ¸ããã¨ã¯é¿ããã¹ãã§ããã
static_assert ( å®æ°å¼ , æååãªãã©ã« ) ;
static_assert宣è¨ã¯ãæ¡ä»¶ä»ãã®ã³ã³ãã¤ã«ã¨ã©ã¼ãå¼ãèµ·ããããã®å®£è¨ã§ãããstatic_assertã®å®æ°å¼ã¯boolã«å¤æããããçµæãtrueãªãã°ãä½ãããªããçµæãfalseãªãã°ãã³ã³ãã¤ã«ã¨ã©ã¼ãå¼ãèµ·ãããããã°ãã³ã³ãã¤ã«æã®assertã¨ãã¦åãã®ã§ãããçµæãfalseã®å ´åãC++ã®ã³ã³ãã¤ã©ã¼ã¯æååãªãã©ã«ãã¨ã©ã¼ã¡ãã»ã¼ã¸ã¨ãã¦ãä½ããã®æ¹æ³ã§è¡¨ç¤ºããã
static_assert( true, "" ) ; // ã³ã³ãã¤ã«ãéã
static_assert( false, "" ) ; // ã³ã³ãã¤ã«ã¨ã©ã¼
// ã³ã³ãã¤ã«ã¨ã©ã¼
// ä½ããã®æ¹æ³ã§ãhelloã¨è¡¨ç¤ºãããã
static_assert( false, "hello" ) ;
å
·ä½çãªå©ç¨ä¾ã¨ãã¦ã¯ãä»ãintåã®ãµã¤ãºã4ãã¤ãã§ãããã¨ãåæã¨ããã³ã¼ããæ¸ãããã¨ããããã®ã³ã¼ãã¯å½ç¶ãªãããã¼ã¿ããªãã£ããªããããã§ãintåã®ãµã¤ãºã4ãã¤ãã§ã¯ãªãç°å¢ã§ã¯ãã³ã³ãã¤ã«ã¨ã©ã¼ã«ãªã£ã¦ã»ãããããã¯ã以ä¸ã®ããã«æ¸ããã
static_assert( sizeof(int) == 4, "sizeof(int) must be 4") ;
sizeof(int)ã4ã§ã¯ãªãç°å¢ã®C++ã®ã³ã³ãã¤ã©ã¼ã§ã¯ããã®ã³ã¼ãã¯ã³ã³ãã¤ã«ã¨ã©ã¼ã«ãªããã¾ããæååãªãã©ã«ããä½ããã®æ¹æ³ã§è¡¨ç¤ºãããã
ã¾ãå¥ã®ä¾ã§ã¯ã以ä¸ã®ãããªé¢æ°ãããã¨ããã
// ä»æ§ï¼Derivedåã¯Baseåããæ´¾çããã¦ãããã¨
template < typename Base, typename Derived >
void f( Base base, Derived derived )
{
// å¦ç
}
ãã®é¢æ°ã§ã¯ãDerivedã¨ããåã¯ãBaseã¨ããåããæ´¾çããã¦ãããã¨ãåæã¨ããå¦çãè¡ããããã§ãããã¦ã¼ã¶ã¼ããã£ããããã®ãããªè¦æ±ãæºãããªãåã渡ããå ´åãã¨ã©ã¼ã«ãªã£ã¦æ¬²ãããããã¯ã以ä¸ã®ããã«æ¸ããã
#include <type_traits>
template < typename Base, typename Derived >
void f( Base base, Derived derived )
{
static_assert(
!std::is_same<Base, Derived>::value // åãåã§ãªããã°true
&& std::is_base_of<Base, Derived>::value // DerivedãBaseããæ´¾çããã¦ããã°true
, "Derived must derive Base.") ;
// å¦ç
}
struct Base { } ;
struct Derived : Base { } ;
int main()
{
Base b ; Derived d ;
f(b, d) ; // OK
f(b, b) ; // ã¨ã©ã¼
}
ãã®ããã«ããã³ãã¬ã¼ãå¼æ°ã®åãããããããå®ããããè¦æ±ãæºããã¦ããªãå ´åãstatic_assertã使ã£ã¦ã³ã³ãã¤ã«ã¨ã©ã¼ã«ãããã¨ãã§ããã
static_assertã®æååãªãã©ã«ã«ã¯ãåºæ¬ã½ã¼ã¹æåã»ããã使ããã¨ãã§ãããC++ã®å®è£
ã¯ãåºæ¬ã½ã¼ã¹æåã»ãã以å¤ã®æåããã¨ã©ã¼ã¡ãã»ã¼ã¸ã¨ãã¦è¡¨ç¤ºãã義åããªããæã
æ¥æ¬äººã¨ãã¦ã¯ãæ¥æ¬èªã使ãããã¨ããã ãããã¹ã¦ã®ã³ã³ãã¤ã©ã¼ã«æ¥æ¬èªã®æåã³ã¼ãã®ãµãã¼ãã義åã¥ããã®ãç¾å®çã§ã¯ãªãããã®ããè¦æ ¼ã§ã¯ãç¾å®çã«æä½éä¿è¨¼ã§ããæåãããµãã¼ãã義åã¥ãã¦ããªãããã¡ãããã³ã³ãã¤ã©ã¼ãstatic_assertã®æ¥æ¬èªè¡¨ç¤ºããµãã¼ãããã®ã¯èªç±ã§ããããããããµãã¼ããã義åããªã以ä¸ãstatic_assertã®æååãªãã©ã«ã«åºæ¬ã½ã¼ã¹æåã»ãã以å¤ã®æåã使ãã®ã¯ããã¼ã¿ããªãã£ä¸ã®åé¡ãããã
// æååãªãã©ã«ã表示ããããã©ããã¯å®è£
ä¾å
static_assert( sizeof(int) == 4, u"ãã®ã³ã¼ãã¯intåã®ãµã¤ãºã¯4ã§ãããã¨ãåæã«ãã¦ãã" ) ;
æå®åã«ã¯ãã¹ãã¬ã¼ã¸ã¯ã©ã¹æå®åãé¢æ°æå®åãtypedefæå®åãfriendæå®åãconstexpræå®åãåæå®åãããã
æå®åã¯ãçµã¿åããã¦ä½¿ããã¨ãã§ããå ´åããããä¾ãã°ãtypedefæå®åã¨åæå®åã¯ãçµã¿åããã¦ä½¿ããã¨ãã§ããããã®éãæå®åã®é çªã«ã¯ãæå³ãç¡ãã以ä¸ã®2è¡ã®ã³ã¼ãã¯ãå
¨ãåãæå³ã§ããã
// intåã®å¥åtypeã宣è¨
// typedefã¯typedefæå®åãintã¯åæå®åãtypeã¯å®£è¨å
typedef int type ;
int typedef type ;
ãã¡ãããæå®åã¨å®£è¨åã¯éãã®ã§ã以ä¸ã¯ã¨ã©ã¼ã§ããã
// ã¨ã©ã¼ã*ã¯å®£è¨åã宣è¨åã®å¾ã«æå®åãæ¸ãäºã¯ã§ããªã
int * typedef type ;
ã¹ãã¬ã¼ã¸ã¯ã©ã¹æå®åã«ã¯ãregisterãstaticãthread_localãexternãmutableãããã
ã²ã¨ã¤ã®å®£è¨ã®ä¸ã«ã¯ãã²ã¨ã¤ã®ã¹ãã¬ã¼ã¸ã¯ã©ã¹æå®åããæ¸ãäºã¯ã§ããªããã¤ã¾ããã¹ãã¬ã¼ã¸ã¯ã©ã¹æå®åå士ã¯ãçµã¿åããã¦ä½¿ããã¨ãã§ããªãããã ããthread_localã ãã¯ãstaticãexternã¨ä½µç¨ã§ããã
registeræå®åã使ã£ã¦ã¯ãªããªããregisterã¯ãå¤æ°ã¸ã®æé©åã®ãã³ãã示ãç®çã§å°å
¥ããããããã¯ãã¾ã ãã¼ãã¦ã§ã¢ãååã«é«éã§ãªãã®ã§ãè³¢ãã³ã³ãã¤ã©ãå®è£
ã§ããªãã£ãå½æã¨ãã¦ã¯ãæå³ã®ããæ©è½ã§ãã£ããããããç¾å¨ã§ã¯ããã¼ãã¦ã§ã¢ã®æ§è½ã®åä¸ã«ãããã³ã³ãã¤ã©ã¼ã¯ããè¤éã§é«æ©è½ãªå®è£
ãã§ããããã«ãªããregisterã¯åã«ç¡è¦ããããã®ã¨ãªã£ã¦ãã¾ã£ãã
registerã¯æ´å²ççç±ã«ããåå¨ããããã®æ©è½ã¯ãç¾å¨ã§ã¯äºææ§ã®ããã ãã«æ®ããã¦ããæ©è½ã§ããã使ç¨ãæ¨å¥¨ããã¦ããªããã¾ããå°æ¥çã«ã¯å»æ¢ãããã ããã
thread_localæå®åã®ããå¤æ°ã¯ãã¹ã¬ããã¹ãã¬ã¼ã¸ã®æå¹æéãæã¤ãããªãã¡ãthread_localãæå®ãããå¤æ°ã¯ãã¹ã¬ãããã¨ã«å¥ã®ãªãã¸ã§ã¯ããæã¤ãã¨ã«ãªãã
thread_localæå®åã¯ãåå空éã¹ã³ã¼ãããããã¯ã¹ã³ã¼ãã®ä¸ã®å¤æ°ã¨ãstaticãã¼ã¿ã¡ã³ãã¼ã«å¯¾ãã¦é©ç¨ãããã¨ãã§ããããããã¯ã¹ã³ã¼ãã®å¤æ°ã«thread_localãæå®ãããå ´åã¯ããã¨ãstaticæå®åãæ¸ããã¦ããªãã¦ããæé»çã«staticã¨æå®ããããã¨ã«ãªãã
æ£ããä¾
// ã°ãã¼ãã«åå空éã®ã¹ã³ã¼ã
thread_local int global_variable ;
// ååã®ä»ãã¦ããåå空éã®ã¹ã³ã¼ã
namespace perfect_cpp
{
thread_local int variable ;
}
// ãããã¯ã¹ã³ã¼ã
void f()
{
// 以ä¸ã®3è¡ã¯ããã¹ã¦thread_localãã¤staticãªå¤æ°ã§ããã
thread_local int a ;
thread_local static int b ;
static thread_local int c ;
}
struct C
{
// 以ä¸ã®2è¡ã¯ããã¹ã¦thread_localãªstaticãã¼ã¿ã¡ã³ãã¼ã§ããã
static thread_local int a ;
thread_local static int b ;
} ;
thread_localæå®åã¯ãstaticãã¼ã¿ã¡ã³ãã¼ã«ããæå®ã§ããªãã¨ãããã¨ã«ã¯ã注æãè¦ããããã¼ã¿ã¡ã³ãã¼ãstaticãã¼ã¿ã¡ã³ãã¼ã¨ãªãã«ã¯ãstaticæå®åããªããã°ãªããªãããããã¯ã¹ã³ã¼ãå
ã®å¤æ°ã¨ã¯éããæé»ã®ãã¡ã«staticãæå®ããããã¨ã«ã¯ãªããªãã
struct C
{
// ã¨ã©ã¼ãthread_localã¯éstaticãã¼ã¿ã¡ã³ãã¼ã«ã¯é©ç¨ã§ããªãã
thread_local int a ;
} ;
thread_localãæå®ãããå¤æ°ã«å¯¾ãããåã宣è¨ã¯ããã¹ã¦thread_localæå®ããã¦ããªããã°ãªããªãã
// 翻訳åä½ 1
thread_local int value ;
// 翻訳åä½ 2
extern thread_local int value ;
// 翻訳åä½ 2
extern int value ; // ã¨ã©ã¼ãthread_localãæå®ããã¦ããªã
staticæå®åã«ã¯ãå¤æ°ãstaticå¤æ°ã«ããã¨ããæ©è½ã¨ãååãå
é¨ãªã³ã±ã¼ã¸ã«ããã¨ããæ©è½ããããstaticæå®åã¯ãå¤æ°ã¨é¢æ°ã¨ç¡åunionã«æå®ãããã¨ãã§ããããã ãããããã¯ã¹ã³ã¼ãå
ã®é¢æ°å®£è¨ã¨ãé¢æ°ã®ä»®å¼æ°ã«æå®ãããã¨ã¯ã§ããªãã
struct C
{
// staticãã¼ã¿ã¡ã³ãã¼
static int data ;
// staticã¡ã³ãã¼é¢æ°
static void f() {}
} ;
int main()
{
// å¤æ°ãstaticå¤æ°ã«ãªã
static int x ;
// ç¡åunionãstaticå¤æ°ã«ãªã
static union { int i ; float f ; } ;
}
staticæå®åãæå®ãããå¤æ°ã¯ãéçã¹ãã¬ã¼ã¸ã®æå¹æéãæã¤ããã ããthread_localæå®åãæå®ããã¦ããå ´åã¯ãã¹ã¬ããã¹ãã¬ã¼ã¸ã®æå¹æéãæã¤ã
ã¯ã©ã¹ã®ã¡ã³ãã¼ã«å¯¾ããstaticæå®åã«ã¤ãã¦ã¯ãstaticã¡ã³ãã¼ãåç
§ã
staticæå®åã¨ãªã³ã±ã¼ã¸ã®é¢ä¿ã«ã¤ãã¦ã¯ãããã°ã©ã ã¨ãªã³ã±ã¼ã¸ãåç
§ã
åå空éã¹ã³ã¼ãã«ãããããªã³ã±ã¼ã¸æå®ç®çã§ã®staticã®ä½¿ç¨ã¯ãç¡ååå空éã§ä»£ç¨ããæ¹ãããããã®æ©è½ã¯ãC++11ã§éæ¨å¥¨ã«ãããã¯ãã ã£ãããç´åã§è¦ç´ããããçç±ã¯ãæ¢åã®ã³ã¼ããèããã¨ããã®æ©è½ãå°æ¥çã«å»æ¢ãããã¨ã¯ã§ããªãããã§ããã
// ã°ãã¼ãã«åå空éã¹ã³ã¼ã
// å
é¨ãªã³ã±ã¼ã¸ã®æå®
static int x ;
static void f() {}
// ç¡ååå空éã使ã
namespace
{
int x ;
void f() {}
}
externæå®åã«ã¯ãååã®ãªã³ã±ã¼ã¸ãå¤é¨ãªã³ã±ã¼ã¸ã«ããã¨ããæ©è½ã¨ãååã®å®ç¾©ãããªãã¨ããæ©è½ããããexternæå®åã¯ãå¤æ°ã¨é¢æ°ã«é©ç¨ã§ããããã ããã¯ã©ã¹ã®ã¡ã³ãã¼ã¨é¢æ°ã®ä»®å¼æ°ã«ã¯æå®ã§ããªãã
// å¤æ°
extern int i ;
// é¢æ°
extern void f() ;
externæå®åã¨ã宣è¨ã¨å®ç¾©ã®é¢ä¿ã«ã¤ãã¦ã¯ã宣è¨ã¨å®ç¾©ãåç
§ã
externæå®åã¨ãªã³ã±ã¼ã¸ã®é¢ä¿ã«ã¤ãã¦ã¯ãããã°ã©ã ã¨ãªã³ã±ã¼ã¸ãåç
§ã
ãã³ãã¬ã¼ãã®æ示çãªã¤ã³ã¹ã¿ã³ã¹åã¨ããªã³ã±ã¼ã¸æå®ã¯ãexternãã¼ã¯ã¼ãã使ãããæå®åã§ã¯ãªãã
mutableæå®åã¯ãconstã§ãstaticã§ããªãã¯ã©ã¹ã®ãã¼ã¿ã¡ã³ãã¼ã«é©ç¨ãããã¨ãã§ãããmutableæå®åã®æ©è½ã¯ãã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã¸ã®constæå®åããç¡è¦ã§ãããã¨ã§ãããããã«ãããconstãªã¡ã³ãã¼é¢æ°ããããã¼ã¿ã¡ã³ãã¼ãå¤æ´ãããã¨ãã§ããã
class C
{
private:
mutable int value ;
public :
void f() const
{
// å¤æ´ã§ãã
value = 0 ;
}
} ;
int main()
{
C c ;
c.f() ;
}
mutableã®æ©è½ã«ã¤ãã¦è©³ããã¯ãCV修飾åãåç
§ã
é¢æ°æå®åï¼Function specifierï¼ã«ã¯ãinlineãvirtualãexplicitãããã
inlineæå®åãæ¸ãããé¢æ°å®£è¨ã¯ãã¤ã³ã©ã¤ã³é¢æ°ï¼inline functionï¼ã宣è¨ãããinlineæå®åã¯ããã®é¢æ°ãã¤ã³ã©ã¤ã³å±éãããã¨ãæã¾ããã¨ç¤ºãããã®æ©è½ã§ããããã ããã¤ã³ã©ã¤ã³é¢æ°ã ããã¨ãã£ã¦ãå¿
ãããã¤ã³ã©ã¤ã³å±éãããããã§ã¯ãªããã¤ã³ã©ã¤ã³é¢æ°ã§ã¯ãªãã¦ããã¤ã³ã©ã¤ã³å±éããããã¨ããããããã¾ã§æé©åã®ãã³ãã«éããªãã
// ã¤ã³ã©ã¤ã³é¢æ°
inline void f() { }
ã¯ã©ã¹å®ç¾©ã®ä¸ã®é¢æ°å®ç¾©ã¯ãinlineæå®åããªãã¦ããèªåçã«inlineé¢æ°ã«ãªãã
struct C
{
// é¢æ°å®ç¾©ãã¤ã³ã©ã¤ã³é¢æ°ã§ãã
void f() {}
// é¢æ°ã®å®£è¨ãã¤ã³ã©ã¤ã³é¢æ°ã§ãã
inline void g() ;
// é¢æ°ã®å®£è¨ãã¤ã³ã©ã¤ã³é¢æ°ã§ã¯ãªã
void h() ;
} ;
// é¢æ°C::gã®å®ç¾©
inline void C::g() { }
// é¢æ°C::hã®å®ç¾©
void C::h() { }
ã¤ã³ã©ã¤ã³æå®åã¯ãé¢æ°ã®ãªã³ã±ã¼ã¸ã«ä½ã®å½±é¿ãä¸ããªããã¤ã³ã©ã¤ã³é¢æ°ã®ãªã³ã±ã¼ã¸ã¯ãé常ã®é¢æ°ã¨åãã§ãããããªãã¡ãstaticæå®åãããã°å
é¨ãªã³ã±ã¼ã¸æã¤ãããã§ãªããã°å¤é¨ãªã³ã±ã¼ã¸ãæã¤ã
// å¤é¨ãªã³ã±ã¼ã¸ãæã¤
inline void f() {}
// å
é¨ãªã³ã±ã¼ã¸ãæã¤
inline static void g() {}
ãã ããã¤ã³ã©ã¤ã³é¢æ°ã¯ãå¤é¨ãªã³ã±ã¼ã¸ãæã£ã¦ããã¨ãã¦ããé常ã®é¢æ°ã¨ã¯ç°ãªãæ±ããåãããããã¯ãã¤ã³ã©ã¤ã³å±éã®å®è£
ã容æã«ããããã®å¶ç´ã§ãããã¤ã³ã©ã¤ã³é¢æ°ã¯ããã®é¢æ°ã使ç¨ãããã¹ã¦ã®ç¿»è¨³åä½ã§ããå®ç¾©ãããã¦ããªããã°ãªããªããã¤ã³ã©ã¤ã³é¢æ°ã®å®ç¾©ã¯ããã¹ã¦ã®ç¿»è¨³åä½ã§ãã¾ã£ããåä¸ã§ãªããã°ãªããªãã
// 翻訳åä½ 1
// translation_unit_1.cpp
// å¤é¨ãªã³ã±ã¼ã¸ãæã¤ã¤ã³ã©ã¤ã³é¢æ°ã®å®ç¾©
inline void f() {}
inline void g() {}
// 翻訳åä½ 2
// translation_unit_2.cpp
// 宣è¨ã ã
inline void f() ;
// å®ç¾©
inline void g() {}
// é¢æ°ã®å®£è¨
int main()
{
// ã¨ã©ã¼
// ãã®ç¿»è¨³åä½ã«é¢æ°fã®å®ç¾©ããªã
f() ;
// OKãå®ç¾©ããã
g() ;
}
ããã¯ããã³ãã¬ã¼ãã¨åããããªå¶éã¨ãªã£ã¦ããããã®ãããå¤é¨ãªã³ã±ã¼ã¸ãæã¤ã¤ã³ã©ã¤ã³é¢æ°ã¯ãé常ããããã¼ãã¡ã¤ã«ã«æ¸ããå¿
è¦ãªç¿»è¨³åä½ã§#includeãããã¾ã£ããåä¸ã¨ãããã¨ã«é¢ãã¦ã詳ããã¯ãODRï¼One definition ruleï¼ãåç
§ã
ãã ãã翻訳åä½ã«å®ç¾©ãããã°ããã®ã§ãå¼ã³åºãå ´æã§ã¯ã宣è¨ã ãã ã¨ãã¦ããåé¡ã¯ãªãã
// 宣è¨
inline void f() ;
int main()
{
// ãã§ã«ååfã¯å®£è¨ããã¦ãã¦ããã®ç¿»è¨³åä½ã«å®ç¾©ããã
f() ; // OK
}
// å®ç¾©
inline void f() {}
virtualæå®åã¯ãã¯ã©ã¹ã®éstaticã¡ã³ãã¼é¢æ°ã«æå®ãããã¨ãã§ããã詳ããã¯ãvirtualé¢æ°ãåç
§ã
explicitæå®åã¯ãã¯ã©ã¹å®ç¾©å
ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã¨å¤æé¢æ°ã«æå®ãããã¨ãã§ããã詳ããã¯ãã³ã³ã¹ãã©ã¯ã¿ã¼ã«ããåå¤æã¨ãå¤æé¢æ°ï¼Conversion functionsï¼ãåç
§ã
typedefæå®åã¯ãåã®å¥åã宣è¨ããããã®æå®åã§ããããã®å¥åã®ãã¨ããtypedefåï¼typedef-nameï¼ã¨ãããtypedefåã¯ãåã¨åãããã«æ±ãããã
typedef int integer ;
// ãã以éãtypedefåintegerã¯ãintåã¨ããªãããã«ä½¿ããã
integer main()
{
integer x = 0 ;
integer y = x ;
}
typedefåã¯ãã¨ã¤ãªã¢ã¹å®£è¨ï¼alias-declarationï¼ã§å®£è¨ãããã¨ãã§ããã
using èå¥å = åå ;
using integer = int ;
ã¨ã¤ãªã¢ã¹å®£è¨ã§ã¯ãusingãã¼ã¯ã¼ãã«ç¶ãèå¥åããtypedefåã¨ãªããtypedefæå®åã«ãã£ã¦å®£è¨ãããtypedefåã¨ãã¨ã¤ãªã¢ã¹å®£è¨ã«ãã£ã¦å®£è¨ãããtypedefåã¯ãå
¨ãåãæå³ãæã¤ããã®ãããæ¬æ¸ã§ãtypedefåãã¨è¨è¿°ããã¦ããå ´åãããã¯typedefæå®åã«ãã宣è¨ã§ãããã¨ãã¨ã¤ãªã¢ã¹å®£è¨ã«ãã宣è¨ã§ãããã¨ãçããé©ç¨ããããä¸æ¹ããtypedefæå®åãã¨è¨è¿°ããã¦ããå ´åãã¨ã¤ãªã¢ã¹å®£è¨ã«ã¯å½ã¦ã¯ã¾ããªãã
ã¨ã¤ãªã¢ã¹å®£è¨ã®ææ³ã¯ãtypedefããåããããããä¾ãã°ãé¢æ°ãã¤ã³ã¿ã¼ã®å¥åã宣è¨ãããã¨ããã
// åãæå³
typedef void (*type)(void) ;
using type = void (*)(void) ;
typedefæå®åã¯ãæå®åã§ããã®ã§ãåç´å®£è¨ã¨åãææ³ã§ååã宣è¨ããªããã°ãªããªããusing宣è¨ã¯ãååãå
ã«æ¸ãããã®å¾ã«ãç´ç²ãªååãæ¸ããã¨ãã§ããã
ã¨ã¤ãªã¢ã¹å®£è¨ã¨ãã³ãã¬ã¼ãã«ã¤ãã¦ã¯ããã³ãã¬ã¼ãã¨ã¤ãªã¢ã¹ãåç
§ã
typedefæå®åã¯ãã¯ã©ã¹ä»¥å¤ã®åãã¹ã³ã¼ãå
ã§ãåãåã®typedefåãå宣è¨ãããã¨ãã§ããã
typedef int I ;
typedef int I ; // OKãåãåã®å宣è¨
typedef short I ; // ã¨ã©ã¼ãåãéã
void f()
{
typedef short I ; // OKãå¥ã®ã¹ã³ã¼ããªã®ã§å¥ã®å®£è¨
}
struct Class_Scope
{
typedef int type ;
typedef int type ; // ã¨ã©ã¼ãã¯ã©ã¹ã¹ã³ã¼ãå
ã§ã¯ãåãåã§ãå宣è¨ã§ããªã
} ;
typedefåã¨constã®é¢ä¿ã¯ãä¸è¦ãã¦åããã«ããã
typedef int * type ;
// aã®åã¯int const *
const int * a ;
// bã®åã¯ãint * const
const type b ;
ããã¯ãæå®åã¨å®£è¨åã¨ã®éãã«ããã
const int // æå®å
* a // 宣è¨å
;
const type // æå®åãtypeã®å㯠int *
b // 宣è¨å
;
å¤æ°aã®å ´åãconst intã¸ã®ãã¤ã³ã¿ã¼åã¨ãªããå¤æ°bã®å ´åãconst typeåã¨ãªããtypeã®åã¯ãint *ãªã®ã§ãint *ã¸ã®conståã¨ãªãããã®ãããéãåã¨ãªãã
friendæå®åã«ã¤ãã¦ã¯ãfriendãåç
§ã
constexpræå®åã¯ãconstexprã®å¶ç´ãæºããããå¤æ°ã®å®ç¾©ãé¢æ°ã¨é¢æ°ãã³ãã¬ã¼ãã®å®£è¨ãstaticãã¼ã¿ã¡ã³ãã¼ã®å®£è¨ã«å¯¾ãã¦æå®ã§ããã
constexpr int value = 0 ;
constexpræå®åã使ã£ã¦å®ç¾©ãããå®æ°å¼ã§åæåãããå¤æ°ã¯ãå®æ°å¼ã¨ãã¦ä½¿ããã¨ãã§ããã
void f()
{
constexpr std::size_t size = 10 ;
int a[size] ;
}
constexpræå®åã使ãå¤æ°ã®åã¯ããªãã©ã«åã§ãªããã°ãªããªãã
struct literal
{
int a ;
} ;
struct non_literal
{
non_literal() { }
} ;
int main()
{
constexpr literal a{} ; // OK
constexpr non_literal b{} ; // ã¨ã©ã¼
}
ã³ã³ã¹ãã©ã¯ã¿ã¼ä»¥å¤ã®é¢æ°ã«constexpræå®åãè¨è¿°ããã¨ããã®é¢æ°ã¯ãconstexpré¢æ°(constexpr function)ã¨ãªããã³ã³ã¹ãã©ã¯ã¿ã¼ã«constexpræå®åãè¨è¿°ããã¨ããã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ãconstexprã³ã³ã¹ãã©ã¯ã¿ã¼(constexpr constructor)ã¨ãªããconstexpré¢æ°ã¨constexprã³ã³ã¹ãã©ã¯ã¿ã¼ã¯æé»ã«inlineã«ãªãã
constexpré¢æ°ã®å®ç¾©ã¯ã以ä¸ã®æ¡ä»¶ãæºãããªããã°ãªããªãã
以ä¸ã¯åæ³ãªconstexpré¢æ°ã®ä¾ã§ããã
constexpr int f()
{
return 1 + 1 ;
}
constexpr int g( int x, int y )
{
return x + y + f() ;
}
constexpr int h( unsigned int n )
{
return n == 0 ? 0 : h( n - 11 ) ;
}
以ä¸ã¯ãconstexpré¢æ°ã®å¶ç´ãæºãããªã誤ã£ãã³ã¼ãã®ä¾ã§ããã
// ã¨ã©ã¼ã使ããªãæã®ä½¿ç¨
constexpr int f( )
{
constexpr int x = 0 ;
return x ;
}
// ã¨ã©ã¼ã使ããªãæã®ä½¿ç¨
constexpr int g( bool b )
{
if ( b )
return 1 ;
else
return 2 ;
}
// ã¨ã©ã¼ãreturnæããµãã¤
constexpr int h()
{
return 0 ;
return 0 ;
}
// ã¨ã©ã¼ãæ»ãå¤ã®åããªãã©ã«åã§ã¯ãªã
struct S{ S(){ } } ;
constexpr S i()
{
return S() ;
}
C++11ã®constexpré¢æ°ã®å¶ç´ã¯ã¨ã¦ãå³ãããC++14ã§ã¯ããã®å¶ç´ã¯å¤§å¹
ã«ç·©åãããã
constexprã³ã³ã¹ãã©ã¯ã¿ã¼ã®å®ç¾©ã¯ãä»®å¼æ°ã®åããªãã©ã«ã§ãªããã°ãªããªããé¢æ°ã®æ¬ä½ã¯ã= deleteãã= defaultããè¤åæã§ãªããã°ãªããªããè¤åæã¯ä»¥ä¸ã®å¶ç´ãæºãããªããã°ãªããªãã
-
ã¯ã©ã¹ã¯virtualåºæ¬ã¯ã©ã¹ãæããªããã¨
-
é¢æ°ã®æ¬ä½ã¯é¢æ°tryãããã¯ã§ã¯ãªããã¨
-
é¢æ°ã®æ¬ä½ã®è¤åæã¯ã以ä¸ã®ããããããå«ã¾ãªããã¨
-
nullæ
-
static_assert宣è¨
-
typedef宣è¨ã¨ã¨ã¤ãªã¢ã¹å®£è¨ã§ãã¯ã©ã¹ãenumãå®ç¾©ããªããã®
-
using宣è¨
-
usingãã£ã¬ã¯ãã£ã
-
ã¯ã©ã¹ã®éstaticãã¼ã¿ã¡ã³ãã¼ã¨ãåºæ¬ã¯ã©ã¹ã®ãµããªãã¸ã§ã¯ãã¯ããã¹ã¦åæåããããã¨
-
éstaticãã¼ã¿ã¡ã³ãã¼ã¨åºæ¬ã¯ã©ã¹ã®ãµããªãã¸ã§ã¯ãã®åæåã«é¢ããã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ãconstexprã³ã³ã¹ãã©ã¯ã¿ã¼ã§ãããã¨
-
éstaticãã¼ã¿ã¡ã³ãã¼ã«æå®ãããåæåå¥ã¯å®æ°å¼ã§ãããã¨
struct S
{
int member = 0 ; // å®æ°å¼ã§ãããã¨
constexpr S() { }
} ;
-
ã³ã³ã¹ãã©ã¯ã¿ã¼ã®å®å¼æ°ãä»®å¼æ°ã®åã«å¤æããéã®åå¤æã¯ãå®æ°å¼ã§ãããã¨
constexprã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ãã¦ã¼ã¶ã¼å®ç¾©ã®åæåãè¨è¿°ãããªãã©ã«åã®ã¯ã©ã¹ãæ¸ããã¨ãã§ããã
struct point
{
int x ;
int y ;
constexpr S( int x, int y )
: x(x), y(y)
{ }
} ;
ãã®ãããªãªãã©ã«åã®ã¯ã©ã¹ã¯ãconstexpræå®åã使ã£ãå¤æ°ã§ä½¿ããã
constexpr S s( 10, 10 ) ;
ã©ã®ãããªå®å¼æ°ï¼ç¡å¼æ°é¢æ°ãå«ãï¼ãä¸ãã¦ããconstexprãå®æ°å¼ã«ãªããªãå ´åãã¨ã©ã¼ã¨ãªãã
// OKãå®æ°å¼ã«ãªãå®å¼æ°ããã
constexpr int f( bool b )
{
return b ? throw 0 : 0 ;
}
// ã¨ã©ã¼ã絶対ã«å®æ°å¼ã«ãªããªãã
constexpr int g( )
{
throw ;
}
constexpré¢æ°ãã³ãã¬ã¼ãããã¯ã©ã¹ãã³ãã¬ã¼ãã®constexprã¡ã³ãã¼é¢æ°ã®ã¤ã³ã¹ã¿ã³ã¹åãããç¹æ®åããconstexpré¢æ°ã®å¶ç´ãæºãããªãå ´åããã®ãããªé¢æ°ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ãconstexpré¢æ°ãconstexprã³ã³ã¹ãã©ã¯ã¿ã¼ã¨ã¯ã¿ãªãããªãã
template < typename T >
constexpr T f( T x )
{
return x ;
}
struct non_literal { non_literal(){ } } ;
int main()
{
f( 0 ) ; // OKãconstexpré¢æ°
non_literal n ;
f( n ) ; // OKããã ãé常ã®é¢æ°
}
constexpré¢æ°ãå¼ã³åºããçµæã®å¤ã¯ãåçã ãconstexprã§ã¯ãªãé¢æ°ãå¼ã³åºããçµæã®å¤ã¨çãããªãã
ã³ã³ã¹ãã©ã¯ã¿ã¼ãé¤ãéstaticã¡ã³ãã¼é¢æ°ã«constexpræå®åã使ãã¨ããã®ã¡ã³ãã¼é¢æ°ã¯const修飾ãããã
struct S
{
constexpr int f() ; // constã«ãªã
} ;
ããã¯ã以ä¸ã®ããã«æ¸ãã®ã¨åçã§ããã
constexpr int f() const ;
constexpræå®åã¯ããã以å¤ã«ã¯é¢æ°ã®åã«å½±é¿ãä¸ããªãã
constexpréstaticã¡ã³ãã¼é¢æ°ãæã¤ã¯ã©ã¹ã¯ããªãã©ã«åã§ãªããã°ãªããªãã
// OKããªãã©ã«å
struct literal
{
constexpr int f() { return 0 ; }
} ;
// ã¨ã©ã¼ããªãã©ã«åã§ã¯ãªã
struct non_literal
{
non_literal() { }
constexpr int f() { return 0 ; }
} ;
constexpræå®åãå¤æ°å®ç¾©ã«ä½¿ãããå ´åãå¤æ°ã¯constã«ãªããå¤æ°ã®åã¯ãªãã©ã«åã§ãªããã°ãªãããã¾ãåæåãããªããã°ãªããªãã
constexpr int a = 0 ;
// ã¨ã©ã¼ãåæåããã¦ããªã
constexpr int b ;
struct non_literal { non_literal() { } } ;
// ã¨ã©ã¼ããªãã©ã«åã§ã¯ãªã
constexpr non_literal c{ } ;
åæåã«ã³ã³ã¹ãã©ã¯ã¿ã¼å¼ã³åºããè¡ãããå ´åãã³ã³ã¹ãã©ã¯ã¿ã¼å¼ã³åºãã¯å®æ°å¼ã§ãªããã°ãªããªãã
åæå®åï¼type specifierï¼ã«ã¯ãã¯ã©ã¹æå®åãenumæå®åãåç´åæå®åï¼simple-type-specifierï¼ãè¤éåæå®åï¼elaborated-type-specifierï¼ãtypenameæå®åãCV修飾åï¼cv-qualifierï¼ãããã
ã¯ã©ã¹æå®åã¯ã¯ã©ã¹ã§ãenumæå®åã¯enumã®å®£è¨ã§ãtypenameæå®åã¯ããã³ãã¬ã¼ãã®åå解決ãåç
§ã
åæå®åã¯ãä¸é¨ãé¤ãã¦ã宣è¨ã®ä¸ã«ã²ã¨ã¤ã ãæ¸ããã¨ãã§ãããçµã¿åããããã¨ã®ã§ããåæå®åã¯ã以ä¸ã®éãã§ããã
constã¯ãconst以å¤ã®åæå®åã¨çµã¿åããããã¨ãã§ãããvolatileã¯ãvolatile以å¤ã®åæå®åã¨çµã¿åããããã¨ãã§ããã
signedã¨unsignedã¯ãchar, short, int, longãå¾ã«æ¸ããã¨ãã§ããã
shortã¨longã¯ãintãå¾ã«æ¸ããã¨ãã§ããã
longã¯ãdoubleãå¾ã«æ¸ããã¨ãã§ãããlongã¯ãlongãå¾ã«æ¸ããã¨ãã§ããã
long double a = 0.0l ;
long long int b = 0 ;
CV修飾åï¼cv-qualifierï¼ã¯ãæå®åã®ä»ã«ããã¤ã³ã¿ã¼ã®å®£è¨åã«ã使ããã¨ãã§ãããCV修飾åã«ã¯ãconstã¨volatileãããããã®äºã¤ã®ãã¼ã¯ã¼ãã®é æåãã¨ã£ã¦ãCV修飾åã¨å¼ã°ãã¦ãããCV修飾åä»ãã®å¤æ°ã¯ãå¿
ãåæååãå¿
è¦ã§ãããCV修飾åããªãã¸ã§ã¯ãã«ä¸ããå½±é¿ã«ã¤ãã¦ã¯ãåºæ¬äºé
ã®CV修飾åãåç
§ã
const int a = 0 ;
volatile int b = 0 ;
const volatile int c = 0 ;
const int d ; // ã¨ã©ã¼ãåæååããªã
æå®åã®å§ãã«è¿°ã¹ãããã«ãæå®åã®é çªã«æå³ã¯ãªãã®ã§ãconst intã¨int constã¯ãåãæå³ã¨ãªãã
CV修飾åä»ãã®åã¸ã®ãã¤ã³ã¿ã¼ããªãã¡ã¬ã³ã¹ã¯ãå¿
ããããCV修飾åä»ãã®ãªãã¸ã§ã¯ããåç
§ããå¿
è¦ã¯ãªãããã ããCV修飾åãä»ãã¦ããããã«æ¯èãã
int main()
{
int x = 0 ; // éconstãªãªãã¸ã§ã¯ã
x = 0 ; // å¤æ´ã§ãã
int const & ref = x ; // åç
§ãã
ref = 0 ; // ã¨ã©ã¼ãå¤æ´ã§ããªã
}
åç´åæå®åã«ã¯ãåºæ¬åãã¯ã©ã¹åãenumåãtypedefåãautoæå®åãdecltypeæå®åã使ããã¨ãã§ããã
åºæ¬åã«ã¤ãã¦ã¯ãåºæ¬åãåç
§ã
注æãã¹ããã¨ã¨ãã¦ã¯ãsignedãunsignedã¯ãåä½ã§ä½¿ãããã¨ãintåã ã¨ã¿ãªãããã
// signed int
signed a = 0 ;
// unsigned int
unsigned b = 0 ;
ã¾ããshortãlongãlong longã¯ãããããintãçç¥ããããã®ã¨ã¿ãªãããã
// short int
short a = 0 ;
// long int
long b = 0 ;
// long long int
long long c = 0 ;
è¤éåæå®åã®è¤éï¼Elaboratedï¼ã¨ããã®ã¯ããã¾ããµãããã訳èªã§ã¯ãªãããæ¬æ¸ã§ã¯ä¾¿å®ä¸ãelaboratedã«å¯¾ããè¤éã¨ãã訳èªã使ç¨ãããclassãstructãunionãenumãªã©ã®ãã¼ã¯ã¼ãã使ã£ãåæå®åãæãã
struct StructName { } ;
class ClassName { } ;
union UnionName { } ;
enum struct EnumName { value } ;
int main()
{
{
// è¤éåæå®å
struct StructName a ;
class ClassName b ;
union UnionName c ;
enum EnumName d = EnumName::value ;
}
{
// åç´åæå®å
StructName a ;
ClassName b ;
UnionName c ;
EnumName d = EnumName::value ;
}
}
èå¥åã«å¯¾ãããã¼ã¯ã¼ãã¯ãenumã«ã¯enumãã¼ã¯ã¼ãããunionã«ã¯unionãã¼ã¯ã¼ãããã¯ã©ã¹ã«ã¯structãã¼ã¯ã¼ããclassãã¼ã¯ã¼ããããã§ã«è¡ããã宣è¨ã¨ä¸è´ãã¦ä½¿ããªããã°ãªããªãã
class Name { } ;
struct Name a ; // OKãstructãã¼ã¯ã¼ãã§ããã
enum Name b ; // ã¨ã©ã¼ããã¼ã¯ã¼ããä¸ä¸è´
union Name c ; // ã¨ã©ã¼ããã¼ã¯ã¼ããä¸ä¸è´
ããã§ã¯ãå¤æ°ã®å®£è¨ã«å¯¾ããautoæå®åã«ã¤ãã¦èª¬æãããé¢æ°ã®å®£è¨ã«å¯¾ããautoæå®åã«ã¤ãã¦ã¯ã宣è¨åã®é¢æ°ãåç
§ãã¾ããnewå¼ã«ããä¼¼ããããªæ©è½ãããã
å¤æ°ã宣è¨ããéãåæå®åã«autoãã¼ã¯ã¼ããæ¸ãã¨ãå¤æ°ã®åããåæååã®å¼ããæ¨å®ãããã
auto a = 0 ; // int
auto b = 0l ; // long
auto c = 0.0 ; // double
auto d = 0.0l ; // long double
ãã¡ãããåãªããªãã©ã«ã ãã«ã¯ã¨ã©ã¾ããªãããããåæååã«æ¸ããå¼ãªãã°ãä½ã§ã使ããã¨ãã§ããã
int f() { return 0 ; }
bool g(int){ return true ; }
char g(double){ return 'a' ; }
int main()
{
auto a = f() ; // int
// ãã¡ããããªã¼ãã¼ãã¼ã解決ãããã
auto b = g(0) ; // bool
auto c = g(0.0) ; // char
auto d = &f ; // int (*)(void)
}
autoæå®åã¯ãåé·ãªå¤æ°ã®åã®æå®ãçãããã«ãããã¨ããã®ããåæååã®åã¯ãã³ã³ãã¤ã«æã«æ±ºå®ã§ããã®ã§ãããããå¤æ°ã®åãæå®ããã®ã¯ãåé·ã ããã ãã¾ããå¤æ°ã®åãæå®ããã®ããé常ã«é¢åãªå ´åãããã
#include <vector>
#include <string>
int main()
{
std::vector< std::string > v ;
// ååãé·ãã¦é¢å
std::vector< std::string >::iterator iter1 = v.begin() ;
// ç°¡æ½ã«æ¸ãã
auto iter2 = v.begin() ;
}
ãã®å ´åã§ã¯ãstd::vector< std::string >::iteratoråã®å¤æ°ã宣è¨ãã¦ãããautoæå®åã使ããªãã¨ãé常ã«åé·ã«ãªã£ã¦ãã¾ãã
template < typename T1, typename T2 > struct Add { } ;
template < typename T1, typename T2 > struct Sub { } ;
template < typename T1, typename T2 >
Add< T1, T2 > operator + ( T1, T2 )
{
typedef Add< T1, T2 > type ;
return type() ;
}
template < typename T1, typename T2 >
Sub< T1, T2 > operator - ( T1, T2 )
{
typedef Sub< T1, T2 > type ;
return type() ;
}
struct A { } ;
struct B { } ;
int main()
{
A a ; B b ;
auto result = a + b - b + (b - a) ;
}
ãã®å ´åãresultã®åãæ示çã«æ¸ããã¨ããã¨ã以ä¸ã®ããã«ãªããããã¯ã¨ã¦ãã§ã¯ãªãããã¾ã¨ãã«æ¸ãäºã¯ã§ããªãã
Add< Sub< Add< A, B>, B>, Sub< B, A> > result = a + b - b + (b - a) ;
autoæå®åã«ããå¤æ°ã®å®£è¨ã§ã¯ãå¤æ°ã®åã¯ãé¢æ°ã®ãã³ãã¬ã¼ãå®å¼æ°ã®æ¨å®ã¨åãæ¹æ³ã§æ¨å®ãããã
auto u = expr ;
ã¨ããå¼ããã£ãã¨ããã¨ãå¤æ°uã®åã¯ã
template < typename U > void f( U u ) ;
ãã®ãããªé¢æ°ããf(expr)ã¨å¼ã³åºããå ´åã®ããã³ãã¬ã¼ãä»®å¼æ°Uã¨åãåã¨ãªãã
ãã ããautoæå®åã§ã¯ãåæååãåæåãªã¹ãã§ãã£ã¦ããåãæ¨å®ã§ããã¨ããéããããã
// std::initializer_list<int>
auto a = { 1, 2, 3 } ;
// std::initializer_list<double>
auto b = { 1.0, 2.0, 3.0 } ;
// ã¨ã©ã¼ãåãæ¨å®ã§ããªã
auto c = { 1, 2.0 } ;
auto d = { } ;
// OKãæ示çãªãã£ã¹ã
auto e = std::initializer_list<int>{ 1, 2.0 } ;
auto f = std::initializer_list<int>{ } ;
ãã³ãã¬ã¼ãã®å®å¼æ°æ¨å®ã¨åãæ¹æ³ã§åãæ¨å®ããããã«ãé
ååã¯é
åã®è¦ç´ ã¸ã®ãã¤ã³ã¿ã¼ã«ãé¢æ°åã¯é¢æ°ãã¤ã³ã¿âåã«ãªã£ã¦ãã¾ããããã«ã¯æ³¨æãå¿
è¦ã§ããã
void f() { }
int main()
{
int a[1] ;
auto t1 = a ; // int *
auto t2 = f ; // int (*)(void)
}
autoæå®åã¯ãä»ã®æå®åããCV修飾åã宣è¨åã¨çµã¿åããããã¨ãã§ããã
int const expr = 0 ; // exprã®åã¯int const
auto a = expr ; // int
auto const b = expr ; // int const
auto const & c = expr ; // int const &
auto const * d = &expr ; // int const *
static auto e = expr ; // staticæå®åä»ãã®intåã®å¤æ°
ãã®éã®åã®æ±ºå®ããé¢æ°ã®ãã³ãã¬ã¼ãå®å¼æ°ã®æ¨å®ã¨åãã«ã¼ã«ã«ãªãã
宣è¨åã¨åæååã®åãåããªãå ´åã¯ãã¨ã©ã¼ã¨ãªãã
auto & x = 0 ; // ã¨ã©ã¼
ãã®ä¾ã§ã¯ãxã®åã¯ããªãã¡ã¬ã³ã¹åã§ããããåæååã®åã¯ããªãã¡ã¬ã³ã¹åã§ã¯ãªãããã®ãããã¨ã©ã¼ã¨ãªãã
宣è¨åãrvalueãªãã¡ã¬ã³ã¹ã®å ´åã注æãè¦ãããautoæå®åã®åã¯ããã³ãã¬ã¼ãå®å¼æ°ã®æ¨å®ã¨åãæ¹æ³ã§æ±ºå®ãããã®ã§ãlvalueãªãã¡ã¬ã³ã¹ã«ãªããã¨ãããã
int main()
{
int x = 0 ;
int && r1 = x ; // ã¨ã©ã¼ãrvalueãªãã¡ã¬ã³ã¹ãlvalueã§åæåã§ããªã
auto && r2 = x ; // OKããã ããr2ã®åã¯int &
auto && r3 = std::move(x) ; // OKãr3ã®åã¯int &&
}
ããã¯ããã³ãã¬ã¼ãå®å¼æ°ã®æ¨å®ã¨åãã§ããã
template < typename U >
void f( U && u ) { }
int main()
{
int x = 0 ;
f( x ) ; // Uã¯int &
f( std::move(x) ) ; // Uã¯int &&
}
autoæå®åã§å¤æ°ã宣è¨ããå ´åã¯ãå¿
ãåæååããªããã°ãªããªããã¾ãã宣è¨ãããã¨ãã¦ããå¤æ°åããåæååã®ä¸ã§ä½¿ããã¦ãã¦ã¯ãªããªãã
auto a ; // ã¨ã©ã¼ãåæååããªã
auto b = b ; // ã¨ã©ã¼ãåæååã®ä¸ã§å®£è¨ãããã¨ãã¦ããå¤æ°åã使ããã¦ãã
åæååãè¦ç´ ã®åUã®åæåãªã¹ãã®å ´åãautoã®åã¯std::initializer_list<U>ã«ãªãã
// std::initializer_list<int>
auto a = { 1, 2, 3 } ;
宣è¨åãé¢æ°ã®å ´åãautoæå®åã使ã£ã宣è¨ã¯é¢æ°ã«ãªãã
void f() { }
auto (*p)() -> void = &f ;
autoæå®åã使ã£ã¦ãã²ã¨ã¤ã®å®£è¨æã§è¤æ°ã®å¤æ°ã宣è¨ãããã¨ã¯å¯è½ã§ããããã®å ´åãå¤æ°ã®åã¯ãããããã®å®£è¨åã¨åæååããæ¨å®ãããåã«ãªãã
auto a = 0, & b = a, * c = &a ;
ãã®ä¾ã§ã¯ãaã®åã¯intãbã®åã¯int &ãcã®åã¯int *ã¨ãªãããã ãä¸è¬ã«ãã³ã¼ãã®å¯èªæ§ã®åé¡ãããã²ã¨ã¤ã®å®£è¨æã§è¤æ°ã®å¤æ°ã宣è¨ããã®ã¯ãé¿ããã»ããããã
ãã ããè¤æ°ã®å¤æ°ã宣è¨ããå ´åãautoã«ãã£ã¦æ¨å®ãããåã¯ãå¿
ãåãã§ãªããã°ãªããªãã
int x = 0 ;
auto a = x, * b = &x ; // OKãautoã«å¯¾ãã¦æ¨å®ãããåã¯åã
auto c = 0, d = 0.0 ; // ã¨ã©ã¼ãåãåãã§ã¯ãªã
å¾æ¥ã®ãå¤æ°ãèªåã¹ãã¬ã¼ã¸ã®æå¹æéãæã¤ã¨ãããã¨ãæ示çã«æå®ããæå³ã§ã®autoæå®åã¯ãå»æ¢ããããC++11ã§ã¯ãautoãã¼ã¯ã¼ããæã®ææ³ã§ä½¿ç¨ããå ´åãã¨ã©ã¼ã¨ãªãã
auto int x = 0 ; // ã¨ã©ã¼ãC++11ã«ã¯åå¨ããªãæã®æ©è½
decltype ( å¼ )
decltypeã®åã¯ããªãã©ã³ãã®å¼ã®åã«ãªããdecltypeæå®åã®ãªãã©ã³ãã®å¼ã¯ãæªè©ä¾¡å¼ã§ããã
int main()
{
decltype( 0 ) x ; // xã®åã¯int
decltype( x ) y ; // yã®åã¯int
int const c = 0 ;
decltype( c ) z = 0 ; // zã®åã¯int const
}
decltypeæå®åã®åã¯ã以ä¸ã®ãããªé åºã§ãæ¡ä»¶ã®åãã¨ããã§ãä¸ããåªå
çã«æ±ºå®ãããã
decltype(e)ã«å¯¾ãã¦ã
-
ãããeãæ¬å¼§å¼ã§å²ã¾ãã¦ããªããååãã¯ã©ã¹ã®ã¡ã³ãã¼ã¢ã¯ã»ã¹ã§ããã°ãdecltypeã®åã¯ãååeã®åã«ãªãã
int x ;
// decltype(x)ã®åã¯int
decltype(x) t1 ;
class C
{
public :
int value ;
} ;
C c ;
// decltype(c)ã®åã¯ãclass C
decltype(c) t2 ;
// decltype(c.value)ã®åã¯ãint
decltype(c.value) t3 ;
ãããeãé¢æ°å¼ã³åºãããªã¼ãã¼ãã¼ãæ¼ç®åã®å¼ã³åºãã§ããã°ãdecltypeã®åã¯ãé¢æ°ã®æ»ãå¤ã®åã«ãªãããã®éãæ¬å¼§å¼ã¯ç¡è¦ããããeã¨ããååãè¦ã¤ãããªãå ´åããeã®ååããªã¼ãã¼ãã¼ãé¢æ°ã®ã»ããã§ãã£ãå ´åãã¨ã©ã¼ã¨ãªãã
decltypeã®ãªãã©ã³ãã¯æªè©ä¾¡å¼ãªã®ã§ãsizeofãªã©ã¨åãããé¢æ°ãå®éã«å¼ã°ãããã¨ã¯ãªãã
int f() ;
// decltype( f() )ã®åã¯ãint
decltype( f() ) t1 ;
// decltype( (f()) )ã®åã¯ãint
decltype( (f()) ) t2 ;
// ã¨ã©ã¼ãfooã¨ããååã¯è¦ã¤ãããªã
decltype( foo ) t3 ;
// ã¨ã©ã¼ããªã¼ãã¼ãã¼ãé¢æ°ã®ã»ãã
void f(int) ;
void f(short) ;
decltype(f) * ptr ;
-
ãããeãxvalueã§ããã°ãeã®åãTã¨ããå ´åãdecltype(e)ã®åã¯ãT &&ã¨ãªãã
int x ;
// typeã®åã¯int &&
using type = decltype( static_cast< int && >(x) ) ;
-
ãããeãlvalueã§ããã°ãeã®åãTã¨ããå ´åãdecltype(e)ã®åã¯ãT &ã¨ãªãã
int x ;
// decltype( (x) ) ã®åã¯ãint &
using type = decltype( (x) ) ;
æ¡ä»¶ãä¸ããåªå
ãããã¨ãããã¨ã«æ³¨æãeãæ¬å¼§ã§å²ã¾ãã¦ããªãå ´åã¯ããã§ã«1.ã®æ¡ä»¶ã«å½ã¦ã¯ã¾ãã®ã§ããã®æ¡ä»¶ã«ã¯å½ã¦ã¯ã¾ããªãããã®æ¡ä»¶ã¯eãæ¬å¼§ã§å²ã¾ãã¦ããå ´åã§ããã
-
ä¸è¨ä»¥å¤ã®å ´åãdecltypeã®åã¯ãeã®åã¨ãªãã
// decltype(0)ã®åã¯ãint
decltype(0) t1 ;
// decltype("hello")ã®åã¯ãchar const [6]
decltype("hello") t2 = "hello" ;
eãlvalueã§ããããæ¬å¼§å¼ã§å²ã¾ãã¦ããå ´åã¯ããªãã¡ã¬ã³ã¹åã«ãªãã¨ãããã¨ã«ã¯ã注æãè¦ããã
int x = 0 ;
decltype( x ) t1 = x ; // t1ã®åã¯int
decltype( (x) ) t2 = x ; // t2ã®åã¯int &
decltypeã¯ãä»ã®åæå®åã宣è¨åã¨ä½µç¨ã§ããã
int x ;
decltype( x ) * ptr ; // int *
decltype( x ) const & const_ref = x ; // int const &
decltypeã¯ããã¹ããããååã®æå®åã¨ãã¦ä½¿ç¨ã§ããã
struct C
{
typedef int type ;
} ;
int main()
{
C c ;
decltype(c)::type x = 0 ; // int
}
decltypeã¯ãåºæ¬ã¯ã©ã¹ã®æå®åãã¡ã³ãã¼åæååã¨ãã¦ä½¿ç¨ã§ããã
struct Base { } ;
Base base ;
struct Derived
: decltype(base) // decltypeãåºæ¬ã¯ã©ã¹ã¨ãã¦æå®
{
Derived()
: decltype(base) () // ã¡ã³ãã¼åæåå
{ }
} ;
decltypeã¯ãçä¼¼ãã¹ãã©ã¯ã¿ã¼åã¨ãã¦ä½¿ç¨ã§ããã
struct C { } ;
int main()
{
C c ;
c.~decltype(c)() ; // çä¼¼ãã¹ãã©ã¯ã¿ã¼ã®å¼ã³åºã
}
enumæå®åã¯ãååä»ãã®å®æ°ã¨åã宣è¨ãå®ç¾©ãããenumï¼Enumerationï¼ã¯ãæ´å²çã«åæåã¨å¼ã°ãã¦ãããenumåã®ååã¯ãenumåã¨ãããenumã宣è¨ããå®æ°ã®ãã¨ããåæåï¼enumeratorï¼ã¨å¼ã¶ã
// Eã¯enumåãvalueã¯åæå
enum E { value = 0 } ;
æ¬æ¸ã§ã¯ãenumã®æ©è½ãå種é¡ã«å¤§å¥ãã¦è§£èª¬ãããunscoped enumãscoped enumãenumåºåºï¼enum-baseï¼ãenum宣è¨ï¼opaque-enum-declarationï¼ã§ããã
enumæå®å:
enum èå¥åopt enumåºåºopt { åæåãªã¹ã }
enumã¨ãããã¼ã¯ã¼ãã ãã§å®£è¨ããenumã®ãã¨ããunscoped enumã¨ãããunscoped enumã¯ãå¼±ãåä»ãã®enumã宣è¨ãå®ç¾©ãããenumã®å®ç¾©ã¯ãããããå¥ã®åãæã¤ãåæåãªã¹ãã¨ã¯ãã³ã³ãã§åºåãããèå¥åã§ãããååæåã«ã¯ã=ã«ç¶ãã¦å®æ°ãæå®ãããã¨ã§ãå¤ãæå®ã§ããããããenumã®åæååã¨ããããã ããåæåèªä½ã¯ãªãã¸ã§ã¯ãã§ã¯ãªããenumã¯å
é ã®åæåã«åæååããªãå ´åãå¤ã¯0ã«ãªããå
é 以å¤ã®åæåã«åæååããªãå ´åããã®ã²ã¨ã¤åã®åæåã®å¤ã«ã1ãå ç®ããå¤ã«ãªãã
// a = 0, b = 1, c = 2
enum E { a, b, c } ;
// a = 3, b = 4, c = 5
enum E { a = 3, b = 4 , c = 5 } ;
// a = -5, b = -4, c = -3
enum E { a = -5, b, c } ;
// a = 0, b = 1, c = 0, d = 1
enum E { a, b, c = 0, d } ;
宣è¨ããåæåã¯ã次ã®åæåãã使ããã¨ãã§ããã
// a = 0, b = 0, c = 5, d = 3
enum E { a, b = a, c = a + 5, d = c - 2 } ;
enumåã¨unscoped enumã®åæåã¯ãenumæå®åãããã¹ã³ã¼ãã§å®£è¨ãããã
enum GlobalEnum { a, b } ;
GlobalEnum e1 = a ;
GlobalEnum e2 = b ;
int main()
{
enum LocalEnum { c, d } ;
LocalEnum e1 = c ;
LocalEnum e2 = d ;
}
unscoped enumã«ãã£ã¦å®£è¨ãããåæåã¯ãæ´æ°ã®ããã¢ã¼ã·ã§ã³ã«ãã£ã¦ãæé»çã«æ´æ°åã«å¤æã§ãããæ´æ°åã¯ãæ示çãªãã£ã¹ãã«ãã£ã¦ãenumåã«å¤æã§ãããæ´æ°åã®å¤ããenumåã®è¡¨ç¾ã§ããç¯å²ãè¶
ãã¦ããå ´åã®æåã¯ãæªå®ç¾©ã§ããã
enum E { value = 123 } ;
void f()
{
int x = value ; // enum Eããintã¸ã®æé»ã®åå¤æ
E e1 = 123 ; // ã¨ã©ã¼ãintããenum Eã¸ã®æé»ã®åå¤æã¯ã§ããªã
E e2 = static_cast<E>(123) ; // intããenum Eã¸ã®æ示çãªãã£ã¹ã
}
// ã³ãã³ãã®ç¨®é¡ã表ãå®æ°
enum Command { copy, cut, paste } ;
// ã³ãã³ããå¦çããé¢æ°
void process_command( Command id )
{
switch( id )
{
case copy :
// å¦ç
break ;
case cut :
// å¦ç
break ;
case paste :
// å¦ç
break ;
default :
// ã¨ã©ã¼å¦ç
break ;
}
}
ã¯ã©ã¹ã®ã¹ã³ã¼ãå
ã§å®£è¨ãããåæåã®ååã¯ãã¯ã©ã¹ã®ã¡ã³ãã¼ã¢ã¯ã»ã¹æ¼ç®åï¼::, ., ->ï¼ã使ããã¨ã«ãã£ã¦ãåç
§ãããã¨ãã§ããã
struct C
{
enum { value } ;
// ã¯ã©ã¹ã¹ã³ã¼ãã®ãªãã§ã¯ååã®ã¾ã¾åç
§ã§ãã
void f() { value ; }
} ;
int main()
{
C::value ; // ::ã«ããåç
§
C c ;
c.value ; // .ã«ããåç
§
C * p = &c ;
p->value ; // ->ã«ããåç
§
}
unscoped enumã¯ãèå¥åãçç¥ãããã¨ãã§ããã
// èå¥åãã
enum E { a } ;
// èå¥åãªã
enum { b } ;
scoped enumã¯ãå¼·ãåä»ããããenumã§ããã
enum struct èå¥å enumåºåºopt { åæåãªã¹ã } ;
enum class èå¥å enumåºåºopt { åæåãªã¹ã } ;
scoped enumã¯ãenum structãenum classã¨ããé£ç¶ããäºã¤ã®ãã¼ã¯ã¼ãã«ãã£ã¦å®£è¨ãããenum structã¨enum classã¯ãå
¨ãåãæå³ã§ãããã©ã¡ãã使ã£ã¦ããããenumã«ã¯ãã¯ã©ã¹ã®ãããªã¢ã¯ã»ã¹æå®ã¯ãªããscoped enumã®èå¥åã¯çç¥ã§ããªããåæåãªã¹ãã®ææ³ã¯ãunscoped enumã¨å¤ãããªãã
enum struct scoped_enum_1 { a, b, c } ;
enum class scoped_enum_2 { a, b, c } ;
scoped enumã¯ãé常ã«å¼·ãåä»ããæã£ã¦ãããåæåã¯ãscoped enumã宣è¨ããã¦ããã¹ã³ã¼ãã«å°å
¥ããããã¨ã¯ãªããããªãããenumåã«::æ¼ç®åãã¤ãã¦åç
§ããªããã°ãªããªãã
enum struct E { value } ;
value ; // ã¨ã©ã¼ãscoped enumã®åæåã¯ããã®ããã«åç
§ã§ããªã
E::value ; // OK
ãã®ãããåãã¹ã³ã¼ãå
ã§ãåãååã®åæåãæã¤ãè¤æ°ã®scoped enumã宣è¨ãããã¨ãã§ããã
void f()
{
// scoped enumã®å ´å
enum struct Foo { value } ;
enum struct Bar { value } ; // OK
Foo::value ; // enum struct Fooã®value
Bar::value ; // enum struct Barã®value
}
void g()
{
// unscoped enumã®å ´å
enum Foo { value } ;
enum Bar { value } ; // ã¨ã©ã¼ããã§ã«valueã¯å®£è¨ããã¦ããã
}
scoped enumã®åæåã¯ãæé»çã«æ´æ°åã«å¤æãããã¨ã¯ã§ããªããæ示çã«ãã£ã¹ããããã¨ã¯ã§ãããæ´æ°åããenumã¸ã®å¤æã¯ãunscoped enumã¨å¤ãããªããã¤ã¾ããæ示çãªãã£ã¹ããå¿
è¦ã§ããã
enum struct E { value = 123 } ;
int x = E::value ; // ã¨ã©ã¼ãscoped enumã®åæåã¯æé»çã«å¤æã§ããªã
int y = static_cast<int>( E::value ) ; // OKãæ示çãªãã£ã¹ã
E e = static_cast<E>( 123 ) ; // OKãunscoped enumã¨åã
ãã ããswitchæã®ä¸ã®caseã©ãã«ããéåãã³ãã¬ã¼ãå®å¼æ°ã§ã¯ãscoped enumã使ããã¨ãã§ããã
enum struct E { value } ;
template < int N > struct C { } ;
void f( E e )
{
// switchæã®caseã©ãã«
switch( e )
{ case E::value : ; }
// éåãã³ãã¬ã¼ãå®å¼æ°
C< E::value > c ;
}
ããã許ããã¦ããçç±ã¯ãscoped enumã®å
é¨çãªå¤ã¯ä½¿ããªããã®ã®ãå¼·ãåä»ãããããä¸ç¨®ã®ã¦ãã¼ã¯ãªèå¥åã¨ãã¦ãscoped enumã使ããããã«ããããã§ããã
scoped enumã¯ãå¼·ãåä»ããããenumã§ãããscoped enumã¯ãåæåã®å
é¨çãªå¤ã¯ä½¿ããªãããåã«ååä»ãã®ç¶æ
ã表ããã¨ãã§ããå¤æ°ã欲ããå ´åãã¾ãããã¨ãå
é¨çãªå¤ã使ãã«ãã¦ããå¼·ãåä»ãã«ãã£ã¦ãäºç´°ãªãã°ãæªç¶ã«é²ãããå ´åãªã©ã«ä½¿ããã¨ãã§ããã
enumåºåº:
: åæå®å
enumåã¯ãå
é¨çã«ã¯åãªãæ´æ°åã§ããããã®å
é¨çãªæ´æ°åã®ãã¨ããå
é¨åï¼underlying typeï¼ã¨ãããenumåºåºï¼enum-baseï¼ã¯ããã®å
é¨åãæå®ããããã®ææ³ã§ãããenumåºåºã®åã¯ãåºæ¬ã¯ã©ã¹ã®æå®ã¨ããä¼¼ãææ³ã§æå®ãããã¨ãã§ãããenumåºåºã®åæå®åã¯ãæ´æ°åã§ãªããã°ãªããªãã
enumåºåºãæå®ãããenumåã®å
é¨åã¯ãenumåºåºã®åæå®åã®åã«ãªãã
enum E : int { } ; // å
é¨åã¯int
enum struct Foo : int { } ; // å
é¨åã¯int
enum struct Bar : unsigned int { } ; // å
é¨åã¯unsigned int
enum Error : float { } ; // ã¨ã©ã¼ãenumåºåºãæ´æ°åã§ã¯ãªã
enumåºåºãçç¥ãããå ´åãscoped enumã®å
é¨åã¯ãintã«ãªãã
enum struct E { } ; // scoped enumã®ããã©ã«ãã®å
é¨åã¯int
scoped enumã§ãintåã®ç¯å²ãè¶
ããå¤ã®åæåã使ãããå ´åã¯ãæ示çã«enumåºåºãæå®ããªããã°ãªããªãã
unscoped enumã®enumåºåºãçç¥ãããå ´åãå
é¨åã¯æ確ã«å®ãããããã¨ããªãã
enum E { } ; // å
é¨åã¯å®ããããªãã
enumã®å
é¨åãå®ãããã¦ããªãå ´åãå
é¨åã¯ãenumã®åæåããã¹ã¦è¡¨ç¾ã§ããæ´æ°åã«ãªãããã®éãã©ã®æ´æ°åã使ããããã¯ãå®è£
ä¾åã§ãããã©ã®æ´æ°åã§ãããã¹ã¦ã®åæåã表ç¾ã§ããªãå ´åã¯ãã¨ã©ã¼ã¨ãªãã
enum宣è¨ã¯ãæ£å¼ã«ã¯ãopaque-enum-declarationã¨ãããããã¯ãå®ç¾©ãããªãenumã®å®£è¨ã§ãããé¢æ°ãå¤æ°ããå®ç¾©ããã«å®£è¨ã§ããããã«ãenumããå®ç¾©ããã«å®£è¨ãããã¨ãã§ããã
enum èå¥å enumåºåº ;
enum struct èå¥å enumåºåºopt ;
enum class èå¥å enumåºåºopt ;
unscoped enumã®å ´åã¯ãå¿
ãå®ç¾©ã¨ä¸è´ããenumåºåºãæå®ããªããã°ãªããªããscoped enumã®å ´åã¯ãenumåºåºãçç¥ããå ´åãå
é¨åã¯ããã©ã«ãã®intã«ãªãããã ããå®å
¨ã®ããã«ã¯ãenum宣è¨ã¨å¯¾å¿ããenumã®å®ç¾©ã«ã¯ãenumåºåºãæ示çã«æ¸ãã¦ãããã»ããããã
enum struct Foo : unsigned int ; // å
é¨åã¯unsigned int
enum class Bar ; // enumåºåºãçç¥ãããå ´åãå
é¨åã¯int
enum E1 : int ; // å
é¨åã¯int
enum E2 ; // ã¨ã©ã¼ãunscoped enumã®å®£è¨ã§ã¯ãenumåºåºãçç¥ãã¦ã¯ãªããªãã
enum宣è¨ã«ãã£ã¦ã宣è¨ã®ã¿ãããenumåã¯ãé常ã®enumã¨åãããã«ä½¿ç¨ã§ããããã ããåæåã使ããã¨ã¯ã§ããªãããªããªãã°ãåæåã¯å®£è¨ããã¦ããªãããã ã
åæåã使ããã¨ãã§ããªãenum宣è¨ã«ãä½ã®æå³ãããã®ããenum宣è¨ãå°å
¥ãããèæ¯ã«ã¯ããã種ã®å©ç¨æ¹æ³ã§ã¯ããã¹ã¦ã®ç¿»è¨³åä½ã«åæåãå¿
è¦ãªããã¨ãããã®ã ã
ç¡é§ãªå®ç¾©ãçã
// 翻訳åä½ 1
enum ID : int { /* èªåçã«çæãããå¤æ°ã®åæå */ } ;
// 翻訳åä½ 2
enum ID : int ; // enum宣è¨
void f( ID id ) // IDãå¼æ°ã«ã¨ãé¢æ°
{
int x = id ;
id = static_cast<ID>(0) ;
}
翻訳åä½ 1ã§å®ç¾©ããã¦ããenumã®åæåã¯ãå¤é¨ã®ãã¼ã«ã«ãã£ã¦ãèªåçã«çæããããã®ã ã¨ãããããã®å®ç¾©ã¯ãããªãé »ç¹ã«æ´æ°ããããããã翻訳åä½ 2ã§ã¯ãenumã®å
é¨çãªå¤ã使ãããåæåã¨ããååä»ãã®å®æ°ã«ã¯ãããã»ã©æå³ãç¡ãå ´åããã®èªåçã«çæãããå¤æ°ã®åæåã¯ãç¡é§ã§ããããªããªãã°ãenumãçæããããã³ã«ããã¨ã翻訳åä½ 2ã®ã½ã¼ã¹ã³ã¼ãã«å¤æ´ããªããåã³ã³ãã¤ã«ãå¿
è¦ãªãå ´åã§ããããããã³ã³ãã¤ã«ããªãããªããã°ãªããªãããã ã
ãªãenumã®å®ç¾©ãå¿
è¦ãã¨ããã¨ãå®å
¨ãªå®ç¾©ããªããã°ãenumã®å
é¨åã決å®ã§ããªãããã§ãããC++11ã§ã¯ãenumåºåºã«ãã£ã¦ãæ示çã«å
é¨åãæå®ã§ãããããã«ãããenumãå®ç¾©ãã宣è¨ãããã¨ãã§ããããã«ãªã£ãã
åå®å
¨ãªãã¼ã¿ã®ç§å¿
以ä¸ã®ã¯ã©ã¹ãèããã
// ã¯ã©ã¹Cã®ãããã¼ãã¡ã¤ã«
// C.h
enum struct ID { /* èªåçã«çæãããå¤æ°ã®åæå */ } ;
class C
{
public :
// å¤é¨ã«å
¬éããã¡ã³ãã¼
private :
ID id ;
} ;
ãã¦ããã®ã¯ã©ã¹ããè¤æ°ã®ç¿»è¨³åä½ã§ä½¿ãããã¨ããããã®ã¯ã©ã¹ã«ã¯ããã¼ã¿ã¡ã³ãã¼ã¨ãã¦enumåã®å¤æ°ãããããããã¯å¤é¨ã«å
¬éããªããã¯ã©ã¹ã®ä¸ã®å®è£
ã®é½åä¸ã®ãã¼ã¿ã¡ã³ãã¼ã§ãããenumã®åæåã¯ãå¤é¨ãã¼ã«ã§èªåçã«çæããããã®ã¨ããã
ããã¨ããã®ãããã¼ãã¡ã¤ã«ã#includeãã¦ããã½ã¼ã¹ãã¡ã¤ã«ã¯ãenumãèªåçã«çæããããã³ã«ãåã³ã³ãã¤ã«ããªããã°ãªããªãããããããã®ã¯ã©ã¹ã使ãã«ããã£ã¦ãenumã®å®ç¾©ã¯å¿
è¦ãªãã¯ãã§ããããã®å ´åã«ããenum宣è¨ãå½¹ã«ç«ã¤ã
// ã¯ã©ã¹Cã®ãããã¼ãã¡ã¤ã«
// C.h
enum struct ID : int ;
class C { /* ã¡ã³ãã¼ */ } ;
// ã¯ã©ã¹Cã®ã½ã¼ã¹ã³ã¼ã
// C.cpp
enum struct ID : int { /* èªåçã«çæãããå¤æ°ã®åæå */ } ;
// ã¡ã³ãã¼ã®å®è£
ãã®ããã«ãã¦ããã°ãenumã®å®ç¾©ãå¤æ´ããã¦ããã¯ã©ã¹ã®ãããã¼ãã¡ã¤ã«ã#includeãã¦ãã¯ã©ã¹ã使ãã ãã®ã½ã¼ã¹ã³ã¼ãã¾ã§ãåã³ã³ãã¤ã«ããå¿
è¦ã¯ãªããªãã
åå空éã¨ã¯ã宣è¨ã®éã¾ãã«ååãã¤ããæ©è½ã§ãããåå空éã®ååã¯ã::æ¼ç®åã«ãã£ã¦ã宣è¨ãåç
§ããããã«ä½¿ããã¨ãã§ãããåå空éã¯ãè¤æ°å®ç¾©ãããã¨ãã§ãããã°ãã¼ãã«ã¹ã³ã¼ãããä¸ç¨®ã®åå空éã¹ã³ã¼ãã¨ãã¦æ±ãããã
inlineopt namespace èå¥å { åå空éã®æ¬ä½ }
åå空éã¯ãå¥ã®åå空éã¹ã³ã¼ãã®ä¸ããã°ãã¼ãã«ã¹ã³ã¼ãã«æ¸ããã¨ãã§ãããåå空éã®æ¬ä½ã«ã¯ããããã宣è¨ããããã¤ã§ãæ¸ããã¨ãã§ãããããã«ã¯ãåå空éèªèº«ãå«ã¾ããã
// ã°ãã¼ãã«ã¹ã³ã¼ã
namespace NS
{ // NSã¨ããååã®åå空éã®ã¹ã³ã¼ã
// 宣è¨ã®ä¾
int value = 0 ;
void f() { }
class C { } ;
typedef int type ;
}// NSã®ã¹ã³ã¼ããããã¾ã§
int main()
{
// NSåå空éã®ä¸ã®ååã使ã
NS::value = 0 ;
NS::f() ;
NS::C c ;
NS::type t ;
value ; // ã¨ã©ã¼ãååãè¦ã¤ãããªã
}
åå空éã¯ãååã®è¡çªãé²ãããã«ä½¿ããã¨ãã§ããã
// ã°ãã¼ãã«ã¹ã³ã¼ã
int value ;
int value ; // ã¨ã©ã¼ãvalueã¨ããååã¯ãã§ã«å®£è¨ããã¦ãã
// OKãåå空éAã®value
namespace A { int value ; }
// OKãåå空éBã®value
namespace B { int value ; }
int main()
{
value ; // ã°ãã¼ãã«ã¹ã³ã¼ãã®value
A::value ; // åå空éAã®value
B::value ; // åå空éBã®value
}
ã°ãã¼ãã«å¤æ°ã¨ãã¦ãvalueã®ãããªãåãããããã¦èª°ã§ã使ããããååã使ãã®ã¯ãåé¡ãå¤ããããããååä»ãã®åå空éã¹ã³ã¼ãã®ä¸ã§ããã°ãååã®è¡çªãæããã«ãæ°è»½ã«çãã¦ããããããååã使ããã¨ãã§ããã
åå空éã¯ãä½åº¦ã§ãå®ç¾©ãããã¨ãã§ããã
// æåã®å®ç¾©
namespace NS { int x ; }
// äºåº¦ç®ã®å®ç¾©
namespace NS { int y ; }
åå空éã¯ãã¹ãã§ããã
namespace A { namespace B { namespace C { int value ; } } }
int main()
{
A::B::C::value ; // Aã®ä¸ã®ãBã®ä¸ã®ãCã®ä¸ã®value
}
inlineãã¼ã¯ã¼ãã®æ¸ãããåå空éã®å®ç¾©ã¯ãinlineåå空éã§ãããinlineåå空éã¹ã³ã¼ãã®ä¸ã§å®£è¨ãããååã¯ãinlineåå空éã®å¤å´ã®åå空éã®ã¹ã³ã¼ãã®ä¸ã§ã使ããã¨ãã§ããã
inline namespace NS { int value ; }
namespace Outer
{
inline namespace Inner
{
int value ;
}
}
int main()
{
value ; // NS::value
NS::value ;
Outer::value ; // Outer::Inner::value
Outer::Inner::value ;
}
ç¡ååå空é(unnamed namespace)ã¯ãååãã¤ããªãåå空éã®å®£è¨ã§ããã
namespace { }
ç¡ååå空éã¯ãé常ã®ååã¤ãåå空éã¨ã¯éãããã®åå空éã¹ã³ã¼ãå
ã®ã¨ã³ãã£ãã£ããå
é¨ãªã³ã±ã¼ã¸ã«ããã®ã«ä½¿ãããã
namespace
{
int x ; // å
é¨ãªã³ã±ã¼ã¸
}
ããåå空éã¹ã³ã¼ãã®ä¸ã§å®£è¨ãããååãããã®åå空éã®ã¡ã³ãã¼ã¨å¼ã¶ãåå空éã®ã¡ã³ãã¼ã¯ãåå空éã®å¤å´ã§å®ç¾©ãããã¨ãã§ããã
namespace NS
{
void f() ; // é¢æ°fã®å®£è¨
namespace Inner
{
void g() ; // é¢æ°gã®å®£è¨
void h() ; // é¢æ°hã®å®£è¨
}
void Inner::g() { } // é¢æ°gã®å®ç¾©
}
void NS::f() { } // é¢æ°fã®å®ç¾©
void NS::Inner::h() { } // é¢æ°hã®å®ç¾©
ãã ããåå空éã®å¤å´ã§å®ç¾©ããã¦ããããã¨ãã£ã¦ãåå空éã®å¤å´ã®ã¹ã³ã¼ãã«ããååãå°å
¥ãããããã§ã¯ãªããããã¾ã§ãåå空éã®å¤å´ã§ããå®ç¾©ãã§ããã ãã§ããã
namespace èå¥å = åå空éã®åå ;
åå空éã¨ã¤ãªã¢ã¹ï¼Namespace aliasï¼ã¨ã¯ãåå空éã®ååã®å¥åãå®ç¾©ããæ©è½ã§ããã
åå空éã¯ãååã®è¡çªãé²ãã§ããããããããåå空éã®ååèªä½ãè¡çªãã¦ãã¾ããã¨ãããããããé²ãããã«ã¯ãåå空éã®ååã«ã¯ãååã«ã¦ãã¼ã¯ãªååãã¤ããªããã°ãªããªããããããè¡çªããªãååãã¤ãããã¨ããã¨ãã©ããã¦ããçãååãã¤ãããã¨ã¯ã§ããªããªã£ã¦ãã¾ãã
namespace Perfect_cpp
{
int x ;
}
int main()
{
Perfect_cpp::x = 0 ;
}
ãã®ä¾ã§ã¯ãååã«ã¦ãã¼ã¯ãªååãPerfect_cppã使ã£ã¦ããããã®ãããxã¨ããååã®å¤æ°åã§ããè¡çªãæãã使ããã¨ãã§ããããããããã®Perfect_cppã¯é·ãä¸ã«ã大æåã¨ã¢ã³ãã¼ã¹ã³ã¢ã使ã£ã¦ãããã¿ã¤ããã¥ãããããã§ãåå空éã¨ã¤ãªã¢ã¹ã使ãã¨ãå¥åãä»ãããã¨ãã§ããã
namespace Perfect_cpp { int x ; }
int main()
{
namespace p = Perfect_cpp ;
p::x ; // Perfect_cpp::x
}
ãã¹ããããååã«ããçãå¥åãã¤ãããã¨ãã§ããã
namespace Perfect_cpp { namespace Library { int x ; } }
int main()
{
namespace pl = Perfect_cpp::Library ;
pl::x ; // Perfect_cpp::Library::x
}
å¥åã®å¥åãå®ç¾©ãããã¨ãã§ããã
namespace Long_name_is_Looooong { }
namespace long_name = Long_name_is_Looooong ;
namespace ln = long_name ;
åã宣è¨é åã§ãå¥åã¨åå空éã®ååãè¡çªãã¦ã¯ãªããªãã
namespace A { } namespace B { }
// ã¨ã©ã¼ãåã宣è¨é åã§ã¯ãå¥åã¨åå空éã®ååãè¡çªãã¦ã¯ãªããªã
namespace A = B ;
int main()
{
// OKãå¥ã®å®£è¨é åãªãå¯
namespace A = B ;
}
using èå¥å ;
using宣è¨ã¯ã宣è¨ãæ¸ããã¦ãã宣è¨é åã«ãæå®ããååãå°å
¥ãããããã«ãããæ示çã«åå空éåã¨::æ¼ç®åã使ããªãã¦ãããã®å®£è¨é åã§ãååã使ããããã«ãªãã
using宣è¨ããåå空éã®ã¡ã³ãã¼ã«ä½¿ãå ´åãusing宣è¨ãæ¸ããã¦ããã¹ã³ã¼ãã§ã::æ¼ç®åã«ããæ示çãªã¹ã³ã¼ãã®æå®ãªãã«ããã®ååã使ããã¨ãã§ããã
namespace NS { int name ; }
int main()
{
name = 0 ; // ã¨ã©ã¼ãåånameã¯å®£è¨ããã¦ããªã
using NS::name ;
name = 0 ; // NS::nameã¨è§£éããã
NS::name = 0 ; // æ示çãªã¹ã³ã¼ãã®æå®
}
// ãããã¯ã¹ã³ã¼ãå¤ã§ãusing宣è¨ã¯ä½¿ãã
using NS::name ;
using宣è¨ã¯ããã³ãã¬ã¼ãèå¥åãæå®ãããã¨ã¯ã§ããªãããã³ãã¬ã¼ãåã¯æå®ã§ããã
namespace NS
{
template < typename T > class C { } ;
}
int main()
{
using NS::C ; // OKããã³ãã¬ã¼ãåã¯æå®ã§ãã
using NS::C<int> ; // ã¨ã©ã¼ããã³ãã¬ã¼ãèå¥åã¯æå®ã§ããªã
}
using宣è¨ã¯ãåå空éã®ååãæå®ãããã¨ã¯ã§ããªãã
namespace NS { }
using NS ; // ã¨ã©ã¼
using宣è¨ã¯ãscoped enumã®åæåãæå®ãããã¨ã¯ã§ããªãã
namespace NS
{
enum struct E { scoped } ;
enum { unscoped } ;
}
int main()
{
using NS::unscoped ; // OKãunscoped enumã®åæå
using NS::E::scoped ; // ã¨ã©ã¼ãscoped enumã®åæåã¯æå®ã§ããªã
}
using宣è¨ã¯ããã®åã®éãã宣è¨ã§ããããããã£ã¦ãé常éããå¤å´ã®ã¹ã³ã¼ãã®ååãé ããã¨ãã§ãããusingãã£ã¬ã¯ãã£ãã¨ã¯ãéããããã
int name ; // ã°ãã¼ãã«ã¹ã³ã¼ãã®name
namespace NS { int name ; } // NSåå空éã®name
int main()
{
// ããã§ã¯ã¾ã ãååãé ããã¦ã¯ããªã
name = 0 ; // ::nameãæå³ãã
using NS::name ; // ãã®using宣è¨ã¯::nameãé ã
name = 0 ; // NS::nameãæå³ãã
}
using宣è¨ã¯ã宣è¨ãããæç¹ã§ããã§ã«å®£è¨ããã¦ããååããã¹ã³ã¼ãã«å°å
¥ããã宣è¨å ´æããè¦ããªãååã¯ãå°å
¥ãããªãã
namespace NS { void f( int ) { } }
// void NS::f(int)ãã°ãã¼ãã«ã¹ã³ã¼ãã«å°å
¥ãã
// void NS::f(double)ã¯ããã®æç¹ã§ã¯å®£è¨ããã¦ããªãã®ã§ãå°å
¥ãããªã
using NS::f ;
namespace NS { void f( double ) { } }
int main()
{
// ãã®æç¹ã§ãunqualifiedåfã¨ãã¦ååæ¢ç´¢ãããã®ã¯
// void NS::f(int)ã®ã¿
f( 1.23 ) ; // NS::f(int)ãå¼ã¶ã
using NS::f ; // void NS::f(double) ãmainé¢æ°ã®ãããã¯ã¹ã³ã¼ãã«å°å
¥ãã
f( 1.23 ) ; // ãªã¼ãã¼ãã¼ã解決ã«ãããNS::f(double)ãå¼ã¶
}
ãã ãããã³ãã¬ã¼ãã®é¨åçç¹æ®åã¯ããã©ã¤ããªã¼ã¯ã©ã¹ãã³ãã¬ã¼ããçµç±ãã¦æ¢ãã®ã§ããã¨ãusing宣è¨ã®å¾ã«å®£è¨ããã¦ããã¨ãã¦ããçºè¦ãããã
namespace NS
{
template < typename T >
class C { } ;
}
using NS::C ;
namespace NS
{
template < typename T >
class C<T * > { } ; // ãã¤ã³ã¿ã¼åã¸ã®é¨åçç¹æ®å
}
int main()
{
C<int * > c ; // é¨åçç¹æ®åã使ãããã
}
using宣è¨ã¯ãã³ã³ã¹ãã©ã¯ã¿ã¼ã®ç¶æ¿ã«ä½¿ããã¨ãã§ããã詳ããã¯ã該å½ã®é
ç®ãåç
§ãããã§ã¯ãã¯ã©ã¹ã®ã¡ã³ãã¼å®£è¨ã¨ãã¦using宣è¨ã使ãéã®ãææ³ä¸ã®æ³¨æäºé
ã ãã説æããã
ã¯ã©ã¹ã®ã¡ã³ãã¼å®£è¨ã¨ãã¦using宣è¨ã使ãå ´åãåºæ¬ã¯ã©ã¹ã®ã¡ã³ãã¼åãæå®ããªããã°ãªããªããåå空éã®ã¡ã³ãã¼ã¯æå®ã§ããªããusing宣è¨ã¯ãåºæ¬ã¯ã©ã¹ã®ã¡ã³ãã¼åããæ´¾çã¯ã©ã¹ã®ã¹ã³ã¼ãã«å°å
¥ããã
namespace NS { int value ; }
class Base
{
public :
void f() { }
} ;
class Derived : private Base
{
public :
using Base::f ; // OKãåºæ¬ã¯ã©ã¹ã®ã¡ã³ãã¼å
using NS::value ; // ã¨ã©ã¼ãåºæ¬ã¯ã©ã¹ã®ã¡ã³ãã¼ã§ã¯ãªã
} ;
ã¯ã©ã¹ã®ã¡ã³ãã¼å®£è¨ã¨ãã¦ã®using宣è¨ã¯ãåºæ¬ã¯ã©ã¹ã®ã¡ã³ãã¼ã®ååããã¯ã©ã¹ã®ã¡ã³ãã¼ã®ååæ¢ç´¢ã§çºè¦ããããã¨ãã§ããã
struct Base { void f( int ) { } } ;
struct Derived1 : Base
{
void f( double ) { }
} ;
struct Derived2 : Base
{
using Base::f ;
void f( double ) { }
} ;
int main()
{
Derived1 d1 ;
d1.f( 0 ) ; // Derived::f(double)ãå¼ã¶
Derived2 d2 ;
d2.f( 0 ) ; // Base::f(int)ãå¼ã¶
}
Derived1::fã¯ãBase::fãé ãã¦ãã¾ãã®ã§ãBase::fã¯ãªã¼ãã¼ãã¼ã解決ã®åè£é¢æ°ã«ä¸ãããã¨ã¯ãªããDerived2ã§ã¯ãusing宣è¨ã使ã£ã¦ãBase::fãDerived2ã®ã¹ã³ã¼ãã«å°å
¥ãã¦ããã®ã§ããªã¼ãã¼ãã¼ã解決ã®åè£é¢æ°ã¨ãã¦èæ
®ãããã
ã¾ããusing宣è¨ã¯ãåºæ¬ã¯ã©ã¹ã®ã¡ã³ãã¼ã®ã¢ã¯ã»ã¹æå®ãå¤æ´ããç®çã§ã使ããã
class Base
{
int value ;
public :
int get() const { return value ; }
void set( int value ) { this->value = value ; }
} ;
// Baseããprivateã§æ´¾ç
class Derived : private Base
{
public : // Base::getã®ã¿publicã«ãã
using Base::get ;
} ;
ãã®ä¾ã§ã¯ãDerivedã¯Baseããprivateæ´¾çãã¦ããããã ããBase::getã ãã¯ãpublicã«ãããããã®ãããªå ´åã«ãusing宣è¨ã使ããã
using宣è¨ã§ã¯ã©ã¹ã®ã¡ã³ãã¼åãæå®ããå ´åãã¯ã©ã¹ã®ã¡ã³ãã¼å®£è¨ã§ãªããã°ãªããªããã¯ã©ã¹ã®ã¡ã³ãã¼å®£è¨ä»¥å¤ã®å ´æã§ãusing宣è¨ã«ã¯ã©ã¹ã®ã¡ã³ãã¼åãæå®ãã¦ã¯ãªããªãã
struct C
{
int x ;
static int value ;
} ;
int C::value ;
using C::x ; // ã¨ã©ã¼ãããã¯ã¯ã©ã¹ã®ã¡ã³ãã¼å®£è¨ã§ã¯ãªã
using C::value ; // ã¨ã©ã¼ãåä¸
using namespace åå空éå ;
usingãã£ã¬ã¯ãã£ãï¼using directiveï¼ã¯ããã®è¨è¿°ä»¥éã®ã¹ã³ã¼ãã«ãããé修飾ååæ¢ç´¢ã«ãæå®ãããåå空éå
ã®ã¡ã³ãã¼ã追å ããããã®æ示æã§ãããusingãã£ã¬ã¯ãã£ãã使ãã¨ãæå®ãããåå空éå
ã®ã¡ã³ãã¼ãã::æ¼ç®åãç¨ããªãã§ä½¿ç¨ã§ããã
namespace NS
{
int a ;
void f() { }
class C { } ;
}
int main()
{
using namespace NS ;
a = 0 ; // NS::a
f() ; // NS::f
C c ; // NS::C
}
usingãã£ã¬ã¯ãã£ãã使ãã°ãæå®ãããåå空éå
ã®ãã¹ã¦ã®ã¡ã³ãã¼ããæ示çãª::æ¼ç®åã使ããã«ã¢ã¯ã»ã¹ã§ããããã«ãªãã
usingãã£ã¬ã¯ãã£ãã¯ãåå空éã¹ã³ã¼ãã¨ãããã¯ã¹ã³ã¼ãå
ã§ä½¿ç¨ãããã¨ãã§ãããã¯ã©ã¹ã¹ã³ã¼ãå
ã§ã¯ä½¿ç¨ã§ããªãã
namespace A { typedef int type ; }
void f()
{
// ãããã¯ã¹ã³ã¼ãå
using namespace A ;
type x ; // A::type
}
namespace B
{
// åå空éã¹ã³ã¼ã
using namespace A ;
type x ; // A::type
}
other_namespace::type g1 ; // A::type
// åå空éã¹ã³ã¼ãï¼ã°ãã¼ãã«ã¹ã³ã¼ãï¼
using namespace A ;
type g2 ; // A::type
class C
{
using namespace A ; // ã¨ã©ã¼ãã¯ã©ã¹ã¹ã³ã¼ãå
ã§ã¯ä½¿ç¨ã§ããªã
} ;
ã°ãã¼ãã«ã¹ã³ã¼ãã«usingãã£ã¬ã¯ãã£ããè¨è¿°ããã®ã¯æ¨å¥¨ã§ããªããç¹ã«ããããã¼ãã¡ã¤ã«ã®ã°ãã¼ãã«ã¹ã³ã¼ãã«usingãã£ã¬ã¯ãã£ããè¨è¿°ããã¨ãé常ã«åé¡ãå¤ããåå空éã®æ¬æ¥ã®ç®çã¯ãååã®è¡çªãé²ãããã§ãããusingãã£ã¬ã¯ãã£ãã¯ãåå空éã¨ããä»çµã¿ã«ç©´ãéãããããªæ©è½ã ããã ã
ããããusingãã£ã¬ã¯ãã£ãã¯å¿
è¦ã§ããããã¨ãã°ãé常ã«é·ãåå空éåããæ·±ããã¹ãããåå空éå
ã®å¤æ°ã®ã¡ã³ãã¼ã使ãå ´åããã¡ãã¡::æ¼ç®åã§æ示çã«ã¹ã³ã¼ããæå®ããããusing宣è¨ã§ã²ã¨ã¤ã²ã¨ã¤å®£è¨ãã¦ããã®ã¯ãé常ã«é¢åã§ããããããããã¯ã¹ã³ã¼ãã§ãååãè¡çªããªãã¨ãããã¨ãä¿è¨¼ã§ãããªãã°ãusingãã£ã¬ã¯ãã£ãã使ã£ã¦ãæ§ããªãã
namespace really_long_name { namespace yet_another_long_name
{
int a ; int b ; int c ; int d ;
} }
void f()
{
// ãã®ã¹ã³ã¼ãã§ã¯ãa, b, c, dã¨ããååã¯è¡çªããªãã¨ä¿è¨¼ã§ãã
using namespace really_long_name::yet_another_long_name ;
a = 0 ; b = 0 ; c = 0 ; d = 0 ;
}
usingãã£ã¬ã¯ãã£ãã¯ã宣è¨ã§ã¯ãªããusingãã£ã¬ã¯ãã£ãã¯ãé修飾ååæ¢ç´¢ã«ãååãæ¢ãã¹ãåå空éããç¹å¥ã«è¿½å ããã¨ããæ©è½ãæã£ã¦ããããããã£ã¦ãusingãã£ã¬ã¯ãã£ãã¯ãååãé ããªãã以ä¸ã®ä¾ã¯ã¨ã©ã¼ã§ãããusing宣è¨ã¨æ¯è¼ããã¨ãéããããã
int name ; // ã°ãã¼ãã«ã¹ã³ã¼ãã®name
namespace NS { int name ; } // NSåå空éã®name
int main()
{
// ããã§ã¯ã¾ã ãååãé ããã¦ã¯ããªã
name = 0 ; // ::nameãæå³ãã
using namespace NS ; // ååæ¢ç´¢ã«NSåå空éå
ã®ã¡ã³ãã¼ã追å
name = 0 ; // ã¨ã©ã¼ã::nameã¨NS::nameã¨ã§ãã©ã¡ãã使ãã¹ããææ§
}
usingãã£ã¬ã¯ãã£ãã¯ãé修飾ååæ¢ç´¢ã«ããå½±é¿ãä¸ããªããADLã«ã¯å½±é¿ãä¸ããªãã
namespace NS
{
struct S { } ;
namespace inner
{
void f(S) { }
void g(S) { }
}
using inner::f ; // inner::fãNSåå空éã«å°å
¥ãã
using namespace inner ; // é修飾ååæ¢ç´¢ã«å½±é¿ããã¼ãã
} ;
int main()
{
NS::S s ;
f(s) ; // OK
g(s) ; // ã¨ã©ã¼ãusingãã£ã¬ã¯ãã£ãã¯ADLã«ã¯å½±é¿ããªã
}
usingãã£ã¬ã¯ãã£ãã§æ¢ç´¢ã§ããããã«ãªã£ãååã¯ããªã¼ãã¼ãã¼ãé¢æ°ã®åè£ã«ããªãã
void f( int ) { }
namespace NS { void f( double ) { } }
int main()
{
// ãã®æç¹ã§ã¯ãNS::fã¯ååæ¢ç´¢ã§çºè¦ãããªã
f( 1.23 ) ; // ::f(int)
using namespace NS ; // NSåå空éã®ã¡ã³ãã¼ãunqualifiedååæ¢ç´¢ã§çºè¦ãããããã«ãªã
f( 1.23 ) ; // ãªã¼ãã¼ãã¼ã解決ã«ãããNS::f( double )
}
usingãã£ã¬ã¯ãã£ãã¯ãunqualifiedååæ¢ç´¢ã®ã«ã¼ã«ãå¤æ´ããã¨ãããé常ã«ç¹æ®ãªæ©è½ã§ãããusingãã£ã¬ã¯ãã£ãã¯ã確å®ã«ååãè¡çªããªããããã¯ã¹ã³ã¼ãå
ã§ä½¿ããããããã¯ããªã¼ãã¼ãã¼ã解決ããããã®ã§ãåãé¢æ°åãè¤æ°ãæå³çã«ååæ¢ç´¢ã§çºè¦ãããå ´åã«ã®ã¿ã使ãã¹ãã§ããã
é¢æ°åãå¤é¨ãªã³ã±ã¼ã¸ãæã¤é¢æ°åãå¤é¨ãªã³ã±ã¼ã¸ãæã¤å¤æ°åã«ã¯ãè¨èªãªã³ã±ã¼ã¸ï¼language linkageï¼ã¨ããæ¦å¿µãããããªã³ã±ã¼ã¸æå®ï¼Linkage specificationï¼ã¯ãè¨èªãªã³ã±ã¼ã¸ãæå®ããããã®ææ³ã§ããããªã³ã±ã¼ã¸æå®ã¨ãã¹ãã¬ã¼ã¸ã¯ã©ã¹æå®åã®externæå®åã¨ã¯ãå¥ç©ã§ããã
注æãå®è£
ä¾åã®è©±ï¼è¨èªãªã³ã±ã¼ã¸ã¯ãC++ã¨ä»ã®ããã°ã©ãã³ã°è¨èªã¨ã®éã§ã®ãé¢æ°åãå¤æ°åã®ç¸äºå©ç¨ã®ããã®æ©è½ã§ãããç°ãªãè¨èªéã§ååãç¸äºå©ç¨ããã«ã¯ãå
±éã®ä»çµã¿ãå¿
è¦ã§ãããããã«ã¯ããã¨ãã°ååãã³ã°ãªã³ã°ãå§ãã¨ãã¦ãã¬ã¸ã¹ã¿ã¼ã®ä½¿ãæ¹ãå¼æ°ã®ã¹ã¿ãã¯ã¸ã®ç©ã¿æ¹ãªã©ã®æ§ã
ãªè¦ç´ ãããããããããããã¯ããããæ¬æ¸ã®ç¯çãè¶
ããã®ã§è§£èª¬ããªãã
extern æååãªãã©ã« { 宣è¨ãªã¹ã }
extern æååãªãã©ã« 宣è¨
æ¨æºã§ã¯ãC++è¨èªãªã³ã±ã¼ã¸ã¨ãCè¨èªãªã³ã±ã¼ã¸ãå®ãã¦ãããC++ã®å ´åãæååãªãã©ã«ã¯"C++"ã¨ãªããCè¨èªã®å ´åãæååãªãã©ã«ã¯"C"ã¨ãªããä½ãæå®ããªãå ´åãããã©ã«ãã§C++è¨èªãªã³ã±ã¼ã¸ã¨ãªããç°ãªããªã³ã±ã¼ã¸æå®ããããååã¯ããã¨ããã®ä»ã®ã·ã°ããã£ã¼ããã¹ã¦åãã§ãã£ãã¨ãã¦ããå¥ã®åã¨ãã¦èªèãããããã®ä»ã®æååãã©ã®ãããªæ±ããåãããã¯ãå®è£
ä¾åã§ããã
// é¢æ°åã¸ã®Cè¨èªãªã³ã±ã¼ã¸ã®æå®
extern "C" typedef void function_type() ;
// é¢æ°åã¸ã®Cè¨èªãªã³ã±ã¼ã¸ã®æå®
extern "C" int f() ;
// å¤æ°åã¸ã®Cè¨èªãªã³ã±ã¼ã¸ã®æå®
extern "C" int value ;
{ }ã使ãæ¹ã®ãªã³ã±ã¼ã¸æå®åã¯ãè¤æ°ã®å®£è¨ã«å¯¾ãã¦ãä¸æ¬ãã¦è¨èªãªã³ã±ã¼ã¸ãæå®ããããã®ææ³ã§ããã
// é¢æ°åf, g, hã¯ããã¹ã¦Cè¨èªãªã³ã±ã¼ã¸ãæã¤
extern "C"
{
void f() ;
void g() ;
void h() ;
}
// C_functions.hã¨ãããããã¼ãã¡ã¤ã«ã§å®£è¨ããã¦ãããã¹ã¦ã®é¢æ°åãé¢æ°åãå¤æ°åã¯ãCè¨èªãªã³ã±ã¼ã¸ãæã¤
extern "C"
{
#include "C_functions.h"
}
ãªã³ã±ã¼ã¸æå®ãããªãå ´åãããã©ã«ãã§C++è¨èªãªã³ã±ã¼ã¸ã ã¨ã¿ãªããããé常ãC++è¨èªãªã³ã±ã¼ã¸ãæå®ããå¿
è¦ã¯ãªãã
// ããã©ã«ãã®C++è¨èªãªã³ã±ã¼ã¸
void g() ;
// æ示çãªæå®
extern "C++" void g() ;
ãªã³ã±ã¼ã¸æå®ã¯ãã¹ããããã¨ãã§ããããã®å ´åãä¸çªå
å´ã®ãªã³ã±ã¼ã¸æå®ã使ããããè¨èªãªã³ã±ã¼ã¸ã¯ãã¹ã³ã¼ããã¤ãããªãã
extern "C"
{
void f() ; // Cè¨èªãªã³ã±ã¼ã¸
extern "C++"
{
void g() ; // C++è¨èªãªã³ã±ã¼ã¸
}
}
ãªã³ã±ã¼ã¸æå®ã¯ãåå空éã¹ã³ã¼ãã®ä¸ã§ã®ã¿ã使ããã¨ãã§ããããããã¯ã¹ã³ã¼ãå
ãªã©ã§ã¯ä½¿ããªãã
Cè¨èªãªã³ã±ã¼ã¸ã¯ãã¯ã©ã¹ã®ã¡ã³ãã¼ã«é©ç¨ãã¦ãç¡è¦ãããã
extern "C"
{
class C
{
void f() ; // C++è¨èªãªã³ã±ã¼ã¸
} ;
}
Cè¨èªãªã³ã±ã¼ã¸ãæã¤ååã®é¢æ°ããè¤æ°ãã£ã¦ã¯ãªããªããããã«ãããCè¨èªãªã³ã±ã¼ã¸ãæã¤é¢æ°ã¯ããªã¼ãã¼ãã¼ãã§ããªãã
extern "C"
{
// ã¨ã©ã¼ãCè¨èªãªã³ã±ã¼ã¸ãæã¤ååã®é¢æ°ãè¤æ°ãã
void f(int) ;
void f(double) ;
}
// OKãäºãã«ç°ãªãè¨èªãªã³ã±ã¼ã¸ãæã¤
void g() ;
extern "C" void g() ;
ãã®ã«ã¼ã«ã¯ããã¨ãé¢æ°ãååä»ãã®åå空éã®ä¸ã§å®£è¨ããã¦ãã¦ããåæ§ã§ããã
namespace A
{
extern "C" void f() ;
}
namespace B
{
extern "C" void f() ; // ã¨ã©ã¼ãA::fã¨B::fã¯åãé¢æ°ãåç
§ãã
void f() ; // OKãC++è¨èªãªã³ã±ã¼ã¸ãæã¤
}
ãã®ããã«ããã¨ãåå空éãéã£ãã¨ãã¦ããCè¨èªãªã³ã±ã¼ã¸ãæã¤é¢æ°ã¯ãååãè¡çªãã¦ã¯ãªããªããããã¯ãåå空éã¨ããä»çµã¿ãåå¨ããªãCè¨èªããã§ã使ããããã«ããããã®ä»æ§ã§ããããã ããCè¨èªãªã³ã±ã¼ã¸ãæã¤é¢æ°ããC++å´ãããåå空éã®ä¸ã§å®£è¨ãã¦ãé常éã使ããã¨ã¯ã§ããã
namespace NS
{
extern "C" void f() { }
}
int main()
{
NS::f() ; // OK
}
ããã«ãããCè¨èªã§æ¸ãããé¢æ°ããä½ããã®åå空éã®ä¸ã«ããã¦ãC++å´ãã使ããã¨ãã§ããã
// ãããã¼ãã¡ã¤ã«ãC_functions.hã¯ãCè¨èªã§æ¸ããã¦ãããã®ã¨ãã
namespace obsolete_C_lib
{
extern "C"
{
#include "C_functions.h"
}
}
NOTE: ã¢ããªãã¥ã¼ãã®è§£èª¬ã¯ãC++14ã¨ãªãäºå®ã®ç¾æç¹ã§ã®ææ°ãã©ãããN3797ãåèã«ãã¦ããã
ã¢ããªãã¥ã¼ã(attribute)ã¯ãå±æ§ã¨ãå¼ã°ããã½ã¼ã¹ã³ã¼ãã«è¿½å çãªæ
å ±ãæå®ããããã®ææ³ã§ããã
ã¢ããªãã¥ã¼ãã®ææ³ã¯ã以ä¸ã®ããã«ãªãã
[[ ã¢ããªãã¥ã¼ããªã¹ã ]]
ã¢ããªãã¥ã¼ãã¯ãææ³ä¸ãå®ã«æ§ã
ãªç®æã«æ¸ããã¨ãã§ãããã¢ããªãã¥ã¼ããªã¹ãã«ã¯ãã¢ããªãã¥ã¼ãç¨ã®ãã¼ã¯ã³ãæå®ãããã¨ãã§ããããã®ãã¼ã¯ã³ã¯ãã¢ããªãã¥ã¼ãã®ä¸ã ãã§éç¨ããèå¥åã§ãããäºç´èªã§ã¯ãªãã
ã¢ããªãã¥ã¼ãã¯ãç¹å®ã®C++å®è£
ã®ç¬èªæ©è½ããç¬èªã®ææ³ã使ããã«è¡¨ç¾ããããã«è¿½å ããããã¾ããC++è¦æ ¼ã§ããã¢ããªãã¥ã¼ãç¨ã®æ©è½ãããã¤ãå®ãã¦ããã
ã¢ã©ã¤ã³(align)ãã¢ã©ã¤ã¡ã³ã(alignment)ã¨ã¯ãããåã®ãªãã¸ã§ã¯ããæ§ç¯ããã¹ãã¬ã¼ã¸ã®ã¢ãã¬ã¹ã«ãå¶ç´ãæå®ããæ©è½ã§ããã
ã¢ã©ã¤ã¡ã³ãæå®åã¯ãé常ã®[[ ]] ã®ãããªã¢ããªãã¥ã¼ãã®ææ³ã使ããªããalignasã¨ãããã¼ã¯ã¼ããä¸ãããã¦ãããå½åãã¢ã©ã¤ã¡ã³ããæå®ããæ©è½ã¯ãã¢ããªãã¥ã¼ãã®ææ³ã使ãäºå®ã ã£ãããã¢ã©ã¤ã¡ã³ãæå®ã®ãããªåºæ¬çãªæ©è½ã«ã¯ãç¬èªã®ãã¼ã¯ã¼ããä¸ããããã¹ãã ã¨ããåæããªããããããç¬èªã®ãã¼ã¯ã¼ããä¸ãããããæå®åã¨ååã¯ã¤ãã¦ãããã®ã®ãã¢ã©ã¤ã¡ã³ãæå®åãç¾ãããã¨ãã§ããç®æã®ææ³ã¯ãã¢ããªãã¥ã¼ãã®ææ³ã«åºã¥ãã¦ããã
ã¢ã©ã¤ã¡ã³ãæå®åã¯ãå¤æ°ã¨ã¯ã©ã¹ã®ãã¼ã¿ã¡ã³ãã¼ã«æå®ã§ãããæ¸ããå ´æã¯ã宣è¨ã®åãããããããã
// OK
alignas(16) char buf[16] ;
struct S
{
// OK
alignas(16) char buf[16] ;
} ;
ãã ããããããã£ã¼ã«ããé¢æ°ã®ä»®å¼æ°ãä¾å¤å®£è¨ãregisterã¹ãã¬ã¼ã¸ã¯ã©ã¹æå®åã¤ãã§å®£è¨ãããå¤æ°ã«ã¯æå®ã§ããªãã
struct S
{
// ã¨ã©ã¼ãããããã£ã¼ã«ã
alignas(4) unsigned int data:16 ;
} ;
// ã¨ã©ã¼ãé¢æ°ã®ä»®å¼æ°
void f( alignas(4) int x ) ;
void g()
{
try { }
// ã¨ã©ã¼ãä¾å¤å®£è¨
catch ( alignas(4) int x ) { }
}
ã¢ã©ã¤ã¡ã³ãæå®åã¯ãã¯ã©ã¹ã®å®£è¨ãå®ç¾©ã«é©ç¨ãããã¨ãã§ãããæ¸ããå ´æã¯ãã¯ã©ã¹ãã¼ã®å¾ãã¯ã©ã¹åã®åã§ããã
struct alignas(16) S ;
struct alignas(16) S { } ;
åæ§ã«ãã¢ã©ã¤ã¡ã³ãæå®åã¯ãenumã®å®£è¨ãå®ç¾©ã«ãé©ç¨ãããã¨ãã§ããã
enum struct alignas(16) E1 : int
{ value } ;
enum alignas(16) E2
{ value } ;
ã¢ã©ã¤ã¡ã³ãæå®åã«ã¨ãªãã·ã¹(...)ãé©ç¨ãããã®ã¯ãããã¯å±éã§ããã
template < typename ... Types >
struct alignas( Types ... ) // ããã¯å±é
S { } ;
ã¢ã©ã¤ã¡ã³ãæå®åã«ã¯ãäºç¨®é¡ã®å½¢ããããalignas( )ã®æ¬å¼§ã®ä¸èº«ããã³ã³ãã§åºåããã代å
¥å¼ã¨ããå½¢ã¨ãã³ã³ãã§åºåãããåã¨ããå½¢ã ã
// 代å
¥å¼
alignas( 4, 8, 16 ) char b1[128] ;
// å
alignas( short, int, long ) char b2[128] ;
ã¢ã©ã¤ã¡ã³ãæå®åãalignas(代å
¥å¼)ã®å½¢ã®å ´åã
-
代å
¥å¼ã¯æ´æ°å®æ°å¼ã§ãªããã°ãªããªã
-
å®æ°å¼ãæ¡å¼µã¢ã©ã¤ã¡ã³ãã§ãããå®è£
ããã®ã¢ã©ã¤ã¡ã³ãããã®æèã§ãµãã¼ããã¦ããå ´åã¯ã宣è¨ãããã¨ã³ãã£ãã£ã®ã¢ã©ã¤ã¡ã³ãã¯ãæå®ãããã¢ã©ã¤ã¡ã³ãã«ãªã
-
å®æ°å¼ãæ¡å¼µã¢ã©ã¤ã¡ã³ãã§ãããå®è£
ããã®ã¢ã©ã¤ã¡ã³ãããã®æèã§ãµãã¼ããã¦ããªãå ´åãã¨ã©ã¼ã¨ãªã
-
å®æ°å¼ãã¼ãã ã¨è©ä¾¡ãããå ´åãã¢ã©ã¤ã¡ã³ãæå®åã®å¹æã¯ãªããªã
ãã以å¤ã®å ´åãã¨ã©ã¼ã¨ãªãã
// OK
constexpr std::size_t f() { return 4 ; }
alignas( f() ) char b1[128] ;
// ã¨ã©ã¼
int g() { return 4 ; }
alignas( g() ) char b2[128] ;
// å®è£
ããµãã¼ããã¦ããå ´åOK
// å®è£
ããµãã¼ããã¦ããªããã°ã¨ã©ã¼
alignas( alignof(std::max_align_t) * 2 ) char b3[128] ;
// OKããã ãã¢ã©ã¤ã¡ã³ãæå®ã®å¹æãªã
alignas( 0 ) char b4[128] ;
ã¢ã©ã¤ã¡ã³ãæå®åããalignas(åå)ã®å ´åãalignas( alignof(å½¢å) )ã¨åçã®å¹æã«ãªãã
// alignas( alignof(int) )ã¨åç
alignas( int ) int x ;
ã²ã¨ã¤ã®ã¨ã³ãã£ãã£ã«è¤æ°ã®ã¢ã©ã¤ã¡ã³ããæå®ãããå ´åãæãå³æ ¼ãªã¢ã©ã¤ã¡ã³ãè¦æ±ã«ãªãã
// ãããå®è£
ã16ã®ã¢ã©ã¤ã¡ã³ãè¦æ±ããµãã¼ããã¦ããå ´å
// ã¢ã©ã¤ã¡ã³ãè¦æ±ã¯16
alignas( 4, 8, 16 ) char b[128] ;
ã¢ã©ã¤ã¡ã³ãæå®åãã宣è¨ãããã¨ã³ãã£ãã£ã®ã¢ã©ã¤ã¡ã³ãè¦æ±ããç·©ãã¢ã©ã¤ã¡ã³ããæå®ããã¨ãã¨ã©ã¼ã¨ãªãã
// Sã®æä½ã®ã¢ã©ã¤ã¡ã³ãè¦æ±ã¯8
struct alignas(8) S { } ;
// ã¨ã©ã¼ãSã®æä½ã®ã¢ã©ã¤ã¡ã³ãè¦æ±ããç·©ã
alignas(4) S s ;
ããã¨ã³ãã£ãã£ã®å®ç¾©ã§ãã宣è¨ã«ã¢ã©ã¤ã¡ã³ãæå®åãããå ´åãåãã¨ã³ãã£ãã£ã®å®ç¾©ã§ã¯ãªã宣è¨ã¯ãåçã®ã¢ã©ã¤ã¡ã³ããæå®ããããã¢ã©ã¤ã¡ã³ãæå®åãªãã§ãªããã°ãªããªãã
struct alignas(8) S { } ;
struct S ; // OK
struct alignas(8) S ; // OK
struct alignas(4) S ; // ã¨ã©ã¼ãåçã§ã¯ãªã
struct alignas(16) S ; // ã¨ã©ã¼ãåçã§ã¯ãªã
ãããã¨ã³ãã£ãã£ã®å®£è¨ã®ã©ããã²ã¨ã¤ã«ã§ãã¢ã©ã¤ã¡ã³ãæå®åããã£ãå ´åããã®ã¨ã³ãã£ãã£ã®å®ç¾©ã¨ãªã宣è¨ã«ããåçã®ã¢ã©ã¤ã¡ã³ããæå®ããªããã°ãªããªãã
struct S { } ; // ã¨ã©ã¼ãã¢ã©ã¤ã¡ã³ãæå®ã¤ãã®å®£è¨ããã
struct alignas(4) S ;
ã¢ããªãã¥ã¼ããã¼ã¯ã³ãnoreturnã¯ãé¢æ°ãreturnããªããã¨ãæå®ããããã®ã¢ããªãã¥ã¼ãã¯ãé¢æ°å®£è¨ã®å®£è¨åidã«é©ç¨ã§ããã
// ãã®é¢æ°ã¯æ±ºãã¦returnããªã
[[ noreturn ]] void f()
{
// ãªããªãã°ãå¿
ãthrowããããã
throw 0 ;
}
noreturnã¯ã宣è¨ä¸ã«ä¸åº¦ããç¾ãã¦ã¯ãªããªããnoreturnãæå®ããé¢æ°ã¯ããã®æåã«ç¾ãã宣è¨ã«ãã®ã¢ããªãã¥ã¼ããé©ç¨ããªããã°ãªããªãã
void f() ; // ã¨ã©ã¼ãæåã®å®£è¨ã ãnoreturnããªã
[[ noreturn ]] void f() ;
ãããããé¢æ°ãããã翻訳åä½ã§ã¯noreturnãæå®ãããå¥ã®ç¿»è¨³åä½ã§ã¯æå®ããã¦ããªãå ´åãã¨ã©ã¼ã¨ãªãã
noreturnãæå®ããé¢æ°ããreturnããå ´åãæåã¯æªå®ç¾©ã§ãããä¾å¤ã«ãã£ã¦æããã®ã¯åé¡ããªãã
ã¯ã©ã¹ã¨ã¯ãã¦ã¼ã¶ã¼ãå®ç¾©ã§ããåã§ãããã¯ã©ã¹ã¯ãã¯ã©ã¹æå®åï¼class-specifierï¼ã«ãã£ã¦å®ç¾©ãããã¯ã©ã¹æå®åã¯æå®åãªã®ã§ã宣è¨æã®ä¸ã§ä½¿ããã¨ãã§ããããããã£ã¦ãã¯ã©ã¹ã®å®ç¾©ã¨ã¯ã宣è¨æã§ããã
ã¯ã©ã¹æå®å:
class-key èå¥åopt finalopt åºæ¬ã¯ã©ã¹æå®opt { ã¡ã³ãã¼æå®opt }
class-key:
class
struct
union
class A { } ;
struct B { } ;
union C { } ;
// ã¯ã©ã¹ã®å®ç¾©ã¯å®£è¨æãªã®ã§ãå¤æ°ããã¤ã³ã¿ã¼ãªã©ãåæã«å®£è¨ã§ããã
class C { } obj, *ptr ;
ã¯ã©ã¹ã®å®ç¾©ã¯ã宣è¨æã§ããããããã£ã¦ãçµç«¯ã«ã¯å¿
ããã»ãã³ãã³ãæ¸ããªããã°ãªããªãã
struct A { } ; // 宣è¨æã®çµç«¯ã«ã¯ã»ãã³ãã³ãå¿
è¦
struct B { } // ã¨ã©ã¼ãã»ãã³ãã³ããªã
ã¯ã©ã¹æå®åã¯ãèå¥åãã¯ã©ã¹åã¨ãã¦ã宣è¨ãããã¹ã³ã¼ãã«å°å
¥ãããã¯ã©ã¹æå®åã®èå¥åã¯çç¥ãããã¨ãã§ããããã®å ´åãç¡åã¯ã©ã¹ã®å®ç¾©ã¨ãªãã
// ç¡åã¯ã©ã¹
class { } a ;
ã¯ã©ã¹æå®åã®ãã¼ã¯ã¼ãã«ã¯ãclassãstructãunionãããããã®ãã¡ãclassã¨structã¯ãããã©ã«ãã®ã¢ã¯ã»ã¹æå®ã®éã以å¤ã¯ãå
¨ãåãã§ããã詳ããã¯ãã¡ã³ãã¼ã®ã¢ã¯ã»ã¹æå®ãåç
§ãunionãã¼ã¯ã¼ãã«ãã£ã¦å®ç¾©ãããã¯ã©ã¹ã¯ãunionã¨ãªãã詳ããã¯ãunionãåç
§ã
ã¯ã©ã¹åã¯ãç¾ããå ´æã®ç´å¾ãããã¹ã³ã¼ãã«å°å
¥ãããã
// ã¯ã©ã¹åã¯ç´å¾ãã使ãã
struct A { } * ptr = static_cast<A *>( nullptr ) ;
ã¾ããã¯ã©ã¹åã¯ããã®ã¯ã©ã¹ã®ã¹ã³ã¼ãå
ã«ãå°å
¥ãããã
struct A
{
// ã¯ã©ã¹åã¯ã¯ã©ã¹ã®ã¹ã³ã¼ãå
ã«ãå°å
¥ããã
typedef A type ;
} ;
ã¯ã©ã¹ã¯ã'}' è¨å·ãç¾ããå ´æ以éãå®å
¨ã«å®ç¾©ããããã®ã¨ã¿ãªãããããã¨ããã¡ã³ãã¼é¢æ°ãå®ç¾©ããã¦ããªãã¦ããã¯ã©ã¹èªä½ã¯ããã®å ´æã§å®ç¾©ããã¦ããã
class A ; // ã¯ã©ã¹Aã¯ä¸å®å
¨å
class A { void f(void) ; } ; // ã¯ã©ã¹Aã¯å®ç¾©ããã
ãã®ä¾ã§ã¯ãA::f(void)ã¯å®ç¾©ããã¦ããªãããã¯ã©ã¹Aã¯ã}ãç¾ããå ´æ以éããã§ã«å®ç¾©ããã¦ããã
ã¯ã©ã¹ã®å®£è¨ã§ãã¯ã©ã¹åã®å¾ãåºæ¬ã¯ã©ã¹ã®åã«finalãè¨è¿°ã§ããã
struct base_class { } ;
struct class_name final : base_class
{ } ;
finalãæå®ãããã¯ã©ã¹ãåºæ¬ã¯ã©ã¹æå®åã«ç¾ããå ´åãã¨ã©ã¼ã¨ãªããã¤ã¾ããfinalãæå®ãããã¯ã©ã¹ããæ´¾çãããã¨ã¯ã§ããªãã
class non_final_class { } ;
// OKãfinalã®æå®ããã¦ããªãã¯ã©ã¹ã¯åºæ¬ã¯ã©ã¹ã«æå®ã§ãã
class ok : non_final_class { } ;
class final_class final { } ;
// ã¨ã©ã¼ãfinalã®æå®ããã¦ããã¯ã©ã¹ã¯åºæ¬ã¯ã©ã¹ã«æå®ã§ããªã
class error : final_class { } ;
å®å
¨åã®ã¯ã©ã¹ã¨ãã®ã¡ã³ãã¼ã®ãªãã¸ã§ã¯ãã¯ãã¼ãã§ã¯ãªããµã¤ãºãæã¤ãã¤ã¾ããsizeofæ¼ç®åã¯ãå°ãªãã¨ãã1以ä¸ãè¿ãã
struct Subobject { } ;
struct Object
{
Subobject sub ;
} ;
int main()
{
Object obj ;
sizeof( obj ) ; // å¤ã¯å®è£
ä¾åã ããå°ãªãã¨ã1以ä¸
sizeof( obj.sub ) ; // åä¸
}
ãã ããåºæ¬ã¯ã©ã¹ã®ãµããªãã¸ã§ã¯ãã¯ãå
é¨çã«ã¯ãµã¤ãºãæããªããããããªããããã¯æé©åã®ããã«è¨±ããã¦ããã
struct Base { } ;
struct Derived : Base { } ;
ãã®å ´åãsizeof(Base)ã¨sizeof(Derived)ã¯ãåãå¤ãè¿ããããããªãã
ããªãã¢ã«ã«ã³ãã¼å¯è½ãªã¯ã©ã¹ï¼trivially copyable classï¼ã¨ã¯ãã¯ã©ã¹ã®ãªãã¸ã§ã¯ããæ§æãããã¤ãåã®å¤ãããã®ã¾ã¾ã³ãã¼ã§ããã¯ã©ã¹ã®ãã¨ã§ããã詳ããã¯ãåãåç
§ã
ããã¯ã©ã¹ãtrivially copyable classã¨ãªãã«ã¯ã以ä¸ã®æ¡ä»¶ããã¹ã¦æºãããªããã°ãªããªãã
étrivialãªãã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ãã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ãã³ãã¼ä»£å
¥æ¼ç®åãã ã¼ã代å
¥æ¼ç®åãæããªããã¨ãtrivialãªãã¹ãã©ã¯ã¿ã¼ãæã£ã¦ãããã¨ã
ã¤ã¾ãããããã®ç¹å¥ãªã¡ã³ãã¼é¢æ°ããã¦ã¼ã¶ã¼å®ç¾©ãã¦ã¯ãªããªããã¾ããvirtualé¢æ°ãvirtualåºæ¬ã¯ã©ã¹ãæã¤ãã¨ã¯ã§ããªããtrivialã®è©³ããå®ç¾©ã«ã¤ãã¦ã¯ãã¯ã©ã¹ãªãã¸ã§ã¯ãã®ã³ãã¼ã¨ã ã¼ããåç
§ã
ããã§ããæããªããã¨ãããã¨ã¯ãdeleteå®ç¾©ã«ãã£ã¦åé¤ãã¦ãæ§ããªãã¨ãããã¨ã§ããã
struct A
{
A( A const & ) =delete ;
A( A && ) = delete ;
A & operator = ( A const & ) = delete ;
A & operator = ( A && ) = delete ;
// trivialãªãã¹ãã©ã¯ã¿ã¼ã¯ããæã£ã¦ãããªããã°ãªããªã
int x ;
} ;
ã¾ããã¢ã¯ã»ã¹æå®åãç°ãªãã¡ã³ãã¼ãæã£ã¦ãã¦ãæ§ããªãã
ä¸è¨ã®ã¯ã©ã¹Aã¯ãã³ãã¼ãã ã¼ããã§ããªãã¯ã©ã¹ã§ããããtrivially copyable classã§ããã
ããªãã¢ã«ã¯ã©ã¹ï¼trivial classï¼ã¨ã¯ãtrivially copyable classã®æ¡ä»¶ã«å ãã¦ãéããªãã¢ã«ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãæããªãã¯ã©ã¹ã§ããã
æ¨æºã¬ã¤ã¢ã¦ãã¯ã©ã¹ï¼standard-layout classï¼ã®è©³ãã説æã«ã¤ãã¦ã¯ãã¯ã©ã¹ã®ã¡ã³ãã¼ãåç
§ã
ããã¯ã©ã¹ãæ¨æºã¬ã¤ã¢ã¦ãã¯ã©ã¹ã¨ãªãããã«ã¯ã以ä¸ã®æ¡ä»¶ããã¹ã¦æºãããªããã°ãªããªãã
æ¨æºã¬ã¤ã¢ã¦ãã¯ã©ã¹ã§ã¯ãªãéstaticã¡ã³ãã¼ããããªããã¾ãããã®ãããªã¯ã©ã¹ã¸ã®é
åããªãã¡ã¬ã³ã¹ãæããªãã
virtualé¢æ°ã¨virtualåºæ¬ã¯ã©ã¹ãæããªãã
éstaticãã¼ã¿ã¡ã³ãã¼ã¯ããã¹ã¦åãã¢ã¯ã»ã¹æå®åã§ããã
// æ¨æºã¬ã¤ã¢ã¦ãã¯ã©ã¹
struct S
{
// ãã¹ã¦åãã¢ã¯ã»ã¹æå®å
int x ;
int y ;
int z ;
// staticãã¼ã¿ã¡ã³ãã¼ã¯ãå¥ã®ã¢ã¯ã»ã¹æå®åã§ããã
private :
static int data ;
} ;
int S::data ;
æ¨æºã¬ã¤ã¢ã¦ãã¯ã©ã¹ã§ã¯ãªãã¯ã©ã¹ãåºæ¬ã¯ã©ã¹ã«æããªãã
åºæ¬ã¯ã©ã¹ã«éstaticãã¼ã¿ã¡ã³ãã¼ãããå ´åã¯ãã¯ã©ã¹ã¯éstaticãã¼ã¿ã¡ã³ãã¼ãæããªããã¯ã©ã¹ãéstaticãã¼ã¿ã¡ã³ãã¼ãæã¤å ´åã¯ãåºæ¬ã¯ã©ã¹ã¯éstaticãã¼ã¿ã¡ã³ãã¼ãæããªããã¤ã¾ããã¯ã©ã¹ã¨ãã®åºæ¬ã¯ã©ã¹ï¼è¤æ°å¯ï¼ã®éåã®ä¸ã§ãã©ããã²ã¨ã¤ã®ã¯ã©ã¹ã ãããéstaticãªãã¼ã¿ã¡ã³ãã¼ãæã¤ãã¨ã許ãããã
struct Empty { } ;
struct Non_empty { int member ; } ;
// 以ä¸ã¯æ¨æºã¬ã¤ã¢ã¦ãã¯ã©ã¹
struct A
// åºæ¬ã¯ã©ã¹ã«éstaticãã¼ã¿ã¡ã³ãã¼ãããå ´å
: Non_empty
{
// éstaticãã¼ã¿ã¡ã³ãã¼ãæããªã
} ;
struct B
// åºæ¬ã¯ã©ã¹ã¯éstaticãã¼ã¿ã¡ã³ãã¼ãæããªã
: Empty
{
// éstaticãã¼ã¿ã¡ã³ãã¼ãæã¤å ´å
int data ;
} ;
// 以ä¸ã¯æ¨æºã¬ã¤ã¢ã¦ãã¯ã©ã¹ã§ã¯ãªã
// åºæ¬ã¯ã©ã¹ãã¯ã©ã¹Cãéstaticãã¼ã¿ã¡ã³ãã¼ãæã£ã¦ãã
struct C
: Non_empty
{
int data ;
} ;
æåã®éstaticãã¼ã¿ã¡ã³ãã¼ã¨ãåºæ¬ã¯ã©ã¹ã¨ã§ãåãåã使ããªãã
// æ¨æºã¬ã¤ã¢ã¦ãã¯ã©ã¹ã§ã¯ãªãä¾
struct A { } ;
struct B
// åºæ¬ã¯ã©ã¹
: A
{
A a ; // æåã®éstaticãã¼ã¿ã¡ã³ãã¼
int data ;
} ;
// æåã®éstaticãã¼ã¿ã¡ã³ãã¼ã§ãªããã°ãã
struct C : A
{
int data ;
A a ;
} ;
ãã®å¶éã¯ãåºæ¬ã¯ã©ã¹ã¨ãã¼ã¿ã¡ã³ãã¼ã¨ã®éã§ãã¢ãã¬ã¹ãéè¤ããã®ãé²ãããã§ããã
struct A { } ;
struct B : A { A a ; } ;
B obj ;
A * p1 = &obj ; // åºæ¬ã¯ã©ã¹ã®ãµããªãã¸ã§ã¯ãã¸ã®ã¢ãã¬ã¹
A * p2 = &obj.a ; // ãã¼ã¿ã¡ã³ãã¼ã¸ã®ã¢ãã¬ã¹
// p1 != p2ãä¿è¨¼ããã
ãã®ãããªå ´åããããã¯ã©ã¹Bãæ¨æºã¬ã¤ã¢ã¦ãã¯ã©ã¹ã§ããã°ãåºæ¬ã¯ã©ã¹ã®ãµããªãã¸ã§ã¯ãã¸ã®ã¢ãã¬ã¹ã¨ããã¼ã¿ã¡ã³ãã¼ã®ãµããªãã¸ã§ã¯ãã¸ã®ã¢ãã¬ã¹ãéè¤ãã¦ãã¾ããã¤ã¾ããp1ã¨p2ãåãå¤ã«ãªã£ã¦ãã¾ããç°ãªãã¢ãã¬ã¹ãå¾ãããããã«ã¯ããã®ãããªã¯ã©ã¹ãæ¨æºã¬ã¤ã¢ã¦ãã¯ã©ã¹ã«ãããã¨ã¯ã§ããªãã
æ¨æºã¬ã¤ã¢ã¦ãã¯ã©ã¹ã®ãã¡ãstructã¨classã®ãã¼ã¯ã¼ãã§å®ç¾©ãããã¯ã©ã¹ããç¹ã«æ¨æºã¬ã¤ã¢ã¦ãstructã¨è¨ããunionãã¼ã¯ã¼ãã§å®ç¾©ãããã¯ã©ã¹ããç¹ã«æ¨æºã¬ã¤ã¢ã¦ãunionã¨ããã
PODã¨ã¯ãPlain Old Dataã®ç¥ã§ãããããã¯ãCè¨èªã®æ§é ä½ã«ç¸å½ããã¯ã©ã¹ã§ãããC++11ã§ã¯ãã¯ã©ã¹ãPODã®æ¡ä»¶ãæºãããéã«ä¿è¨¼ãããåä½ããtrivially copyable classã¨ãæ¨æºã¬ã¤ã¢ã¦ãã¯ã©ã¹ã®äºã¤ã®åä½ã«ç´°ååããããã®ãããC++11ã§ã¯ãç¹ã«PODã«ãã ããå¿
è¦ã¯ãªãã
ã¯ã©ã¹ãPODã¨ãªãããã«ã¯ãtrivial classã¨æ¨æºã¬ã¤ã¢ã¦ãã¯ã©ã¹ã®æ¡ä»¶ãæºãããããã«ãPODã§ã¯ãªãã¯ã©ã¹ãéstaticãã¼ã¿ã¡ã³ãã¼ã«æããªãã¨ããæ¡ä»¶ãå¿
è¦ã«ãªãã
ã¯ã©ã¹å®£è¨ã¯ãã¯ã©ã¹åãã¹ã³ã¼ãã«å°å
¥ãããã¯ã©ã¹åã¯å¤å´ã®ã¹ã³ã¼ãã®ååãé ãã
ãããã¯ã©ã¹åã宣è¨ãããã¹ã³ã¼ãå
ã§ãååã®å¤æ°ãé¢æ°ãenumã宣è¨ãããå ´åã¯ãã©ã¡ãã®å®£è¨ãã¹ã³ã¼ãã«åå¨ãããã¨ã«ãªãããã®å ´åãã¯ã©ã¹åã使ãã«ã¯ãè¤éåæå®åã使ã以å¤ã«æ¹æ³ããªããªãã
void name() { }
class name { } ;
name n ; // ã¨ã©ã¼ãnameã¯é¢æ°å
class name n ; // OKãè¤éåæå®å
ã¯ã©ã¹ã®ã¡ã³ãã¼æå®ã«ã¯ã宣è¨æãé¢æ°ã®å®ç¾©ãusing宣è¨ãstatic_assert宣è¨ããã³ãã¬ã¼ã宣è¨ãã¨ã¤ãªã¢ã¹å®£è¨ãæ¸ããã¨ãã§ããã
struct Base { int value ; } ;
struct S : Base
{
int data_member ; // 宣è¨æ
void member_function() { } // é¢æ°ã®å®ç¾©
using Base::value ; // using宣è¨
static_assert( true, "this must not be an error." ) ; // static_assert宣è¨
template < typename T > struct Inner { } ; // ãã³ãã¬ã¼ã宣è¨
using type = int ; // ã¨ã¤ãªã¢ã¹å®£è¨
} ;
ãã®ãã¡ãã¯ã©ã¹ã®ã¡ã³ãã¼ã¨ãªãã®ã¯ããã¼ã¿ã¡ã³ãã¼ã¨ã¡ã³ãã¼é¢æ°ããã¹ããããååãåæåã§ããã
struct S
{
int x ; // ãã¼ã¿ã¡ã³ãã¼
void f() { } ; // ã¡ã³ãã¼é¢æ°
using type = int ; // ãã¹ããããåå
enum { id } ; // åæå
} ;
ãã¼ã¿ã¡ã³ãã¼ã¯ãä¿ã«ã¡ã³ãã¼å¤æ°ã¨ãå¼ã°ãã¦ãããã¯ã©ã¹å®ç¾©å
ã§ãå¤æ°ã®å®£è¨æãæ¸ãã¨ããã¼ã¿ã¡ã³ãã¼ã¨ãªãã
ã¯ã©ã¹ã®ã¡ã³ãã¼ããã¯ã©ã¹ã®å®ç¾©å
ã§è¤æ°å宣è¨ãããã¨ã¯ã§ããªãããã ããã¯ã©ã¹å
ã®ã¯ã©ã¹ã¨enumã«é¢ãã¦ã¯ãåæ¹å®£è¨ãããã¨ãã§ããã
class Outer
{
void f() ;
void f() ; // ã¨ã©ã¼ãè¤æ°åã®å®£è¨
class Inner ; // ã¯ã©ã¹å
ã¯ã©ã¹ã®å®£è¨
class Inner { } ; // OKãã¯ã©ã¹å
ã¯ã©ã¹ã®å®ç¾©
enum struct E : int ; // ã¯ã©ã¹å
enumã®å®£è¨
enum struct E : int { id } ; // OKãã¯ã©ã¹å
enumã®å®ç¾©
} ;
ã¯ã©ã¹ã¯ã}ã§éããæããã£ã¦ãå®å
¨ã«å®ç¾©ãããã¨ã¿ãªãããããã¨ããã¡ã³ãã¼é¢æ°ãå®ç¾©ããã¦ããªãã¦ããã¯ã©ã¹èªä½ã¯å®å
¨ã«å®ç¾©ãããåã¨ãªãã
ã¡ã³ãã¼ã¯ã³ã³ã¹ãã©ã¯ã¿ã¼ã§åæåã§ããã詳ããã¯ã³ã³ã¹ãã©ã¯ã¿ã¼ãåç
§ãã¡ã³ãã¼ã¯åæååã§åæåã§ããã詳ããã¯ãstaticãã¼ã¿ã¡ã³ãã¼ã¨ãåºæ¬ã¯ã©ã¹ã¨ãã¼ã¿ã¡ã³ãã¼ã®åæåãåç
§ã
struct S
{
S() : x(0) { } // ã³ã³ã¹ãã©ã¯ã¿ã¼
int x = 0 ; // åæåå
static int data ;
} ;
int S::data = 0 ; // åæåå
ã¡ã³ãã¼ã¯ãexternãregisteræå®åã¨å
±ã«å®£è¨ãããã¨ã¯ã§ããªããã¡ã³ãã¼ãthread_localæå®åã¨å
±ã«å®£è¨ããå ´åã¯ãstaticæå®åãæå®ããªããã°ãªããªãã
struct S
{
extern int a ; // ã¨ã©ã¼
register int b ; // ã¨ã©ã¼
thread_local int c ; // ã¨ã©ã¼
// OKãstaticã¨å
±ã«å®£è¨ãã¦ãã
static thread_local int d ;
} ;
thread_local int S::d ; // å®ç¾©
åºæ¬çã«ãã¯ã©ã¹åã¨åãååã®ã¡ã³ãã¼ãæã¤ãã¨ã¯ã§ããªããããã«ã¯ãä¸é¨ã®ä¾å¤ãåå¨ããããæ¬æ¸ã§ã¯è§£èª¬ããªãã
struct name
{
static int name ; // ã¨ã©ã¼
void name() ; // ã¨ã©ã¼
static void name() ; // ã¨ã©ã¼
using name = int ; // ã¨ã©ã¼
enum { name } ; // ã¨ã©ã¼
union { int name } ; // ã¨ã©ã¼
} ;
unionã§ã¯ãªãã¯ã©ã¹ã«ããã¦ãåãã¢ã¯ã»ã¹æå®ä¸ã«ããéstaticãã¼ã¿ã¡ã³ãã¼ã¯ãã¯ã©ã¹ã®ãªãã¸ã§ã¯ãä¸ã§ã宣è¨ãããé çªã«ç¢ºä¿ããããã¤ã¾ããå
ã«å®£è¨ããããã¼ã¿ã¡ã³ãã¼ã¯ãå¾ã«å®£è¨ããããã¼ã¿ã¡ã³ãã¼ããããä¸ä½ã®ã¢ãã¬ã¹ã«é
ç½®ãããããã ããå®è£
ã¯å¿
è¦ãªããã£ã³ã°ãå·®ãæããããããªãã®ã§ãå¾ã®ãã¼ã¿ã¡ã³ãã¼ããå
ã®ãã¼ã¿ã¡ã³ãã¼ã®ç´å¾ã«é
ç½®ãããã¨ããä¿è¨¼ã¯ãªãã
struct S
{
public :
// åãã¢ã¯ã»ã¹æå®ä¸ã«ããéstaticãã¼ã¿ã¡ã³ãã¼
int x ;
int y ;
} ;
int main()
{
S s ;
int * p1 = &s.x ;
int * p2 = &s.y ;
// ãã®å¼ã¯ãå¿
ãtrueã¨ãªã
p1 < p2 ;
// ãã®å¼ãtrueã¨ãªãä¿è¨¼ã¯ãªã
p1 + 1 == p2 ;
}
ã¢ã¯ã»ã¹æå®åãç°ãªãéstaticãã¼ã¿ã¡ã³ãã¼ã®é
ç½®ã«é¢ãã¦ã¯ãæªè¦å®ã§ããã
æ¨æºã¬ã¤ã¢ã¦ãstructã®ãªãã¸ã§ã¯ãã¸ã®ãã¤ã³ã¿ã¼ã¯ãreinterpret_castã«ãã£ã¦å¤æãããå ´åãã¯ã©ã¹ã®æåã®ã¡ã³ãã¼ã¸ã®ãã¤ã³ã¿ã¼ã«å¤æã§ãããã¾ãããã®éãå¯è½ã§ããã
struct S { int x ; } ;
int main()
{
S s ;
S * p1 = &s ;
int * p2 = &s.x ;
// 以ä¸ã®2å¼ã¯ãtrueã¨ãªããã¨ãä¿è¨¼ããã¦ãã
p1 == reinterpret_cast< S * >( p2 ) ;
p2 == reinterpret_cast< int * >( p1 ) ;
}
ã¬ã¤ã¢ã¦ãäºæï¼layout-compatibleï¼ã¨ããæ¦å¿µããããã¾ããåãåã¯ãã¬ã¤ã¢ã¦ãäºæã§ããã
ãããäºã¤ã®æ¨æºã¬ã¤ã¢ã¦ãstructããåãæ°ã®éstaticãã¼ã¿ã¡ã³ãã¼ãæã¡ã対å¿ããéstaticãã¼ã¿ã¡ã³ãã¼ããããããã¬ã¤ã¢ã¦ãäºæã§ãã£ããªãã°ããã®ã¯ã©ã¹ã¯ããäºãã«ã¬ã¤ã¢ã¦ãäºæstructã§ããã
ãããäºã¤ã®æ¨æºã¬ã¤ã¢ã¦ãunionããåãæ°ã®éstaticãã¼ã¿ã¡ã³ãã¼ãæã¡ã対å¿ããéstaticãã¼ã¿ã¡ã³ãã¼ããããããã¬ã¤ã¢ã¦ãäºæã§ãã£ããªãã°ããã®ã¯ã©ã¹ã¯ããäºãã«ã¬ã¤ã¢ã¦ãäºæunionã§ããã
äºã¤ã®æ¨æºã¬ã¤ã¢ã¦ãstructã¯ãã¬ã¤ã¢ã¦ãäºæstructã®ã¡ã³ãã¼ãç¶ãéãããªãã¸ã§ã¯ãä¸ã§å
±éã®è¡¨ç¾ããã¦ããã¨ä¿è¨¼ãããã
// AãBã¯ã2çªç®ã®ã¡ã³ãã¼ã¾ã§ããäºãã«ã¬ã¤ã¢ã¦ãäºæ
struct A
{
int x ;
int y ;
float z ;
} ;
struct B
{
int x ;
int y ;
double z ;
} ;
int main()
{
A a ;
B * ptr = reinterpret_cast< B * >( &a ) ;
// OKãaã®ãªãã¸ã§ã¯ãã®ã対å¿ããã¬ã¤ã¢ã¦ãäºæãªã¡ã³ãã¼ãå¤æ´ããã
ptr->x = 1 ;
ptr->y = 2 ;
// ã¨ã©ã¼ã3çªç®ã®ã¡ã³ãã¼ã¯ãã¬ã¤ã¢ã¦ãäºæã§ã¯ãªã
ptr->z = 0.0 ;
}
ãã ããã¡ã³ãã¼ãããããã£ã¼ã«ãã®å ´åããäºãã«åããããæ°ã§ãªããã°ãªããªãã
// Aã¨Bã¯ãäºãã«ã¬ã¤ã¢ã¦ãäºæ
struct A
{
int x:8 ;
} ;
struct B
{
int x:8 ;
} ;
æ¨æºã¬ã¤ã¢ã¦ãunionãããäºãã«ã¬ã¤ã¢ã¦ãäºæãªè¤æ°ã®æ¨æºã¬ã¤ã¢ã¦ãstructãæã¤ã¨ããå
é ããå
±éã®ã¡ã³ãã¼ã«ã¤ãã¦ã¯ãä¸æ¹ãå¤æ´ãã¦ãä»æ¹ã§ä½¿ããã¨ãã§ããã
struct A
{
int x ;
int y ;
float z ;
} ;
struct B
{
int x ;
int y ;
double z ;
} ;
union U
{
A a ;
B b ;
} ;
int main()
{
U u ;
u.a.x = 1 ;
u.a.y = 2 ;
// 以ä¸ã®2å¼ã¯trueã¨ãªããã¨ãä¿è¨¼ããã¦ãã
u.b.x == 1 ;
u.b.y == 2 ;
// 3çªç®ã®ã¡ã³ãã¼ã¯ãã¬ã¤ã¢ã¦ãäºæã§ã¯ãªã
}
ã¯ã©ã¹ã®å®ç¾©å
ã§å®£è¨ãããé¢æ°ããã¯ã©ã¹ã®ã¡ã³ãã¼é¢æ°ï¼member function)ã¨ãããã¡ã³ãã¼é¢æ°ã¯staticæå®åã¨å
±ã«å®£è¨ãããã¨ãã§ããããã®å ´åãé¢æ°ã¯staticã¡ã³ãã¼é¢æ°ã¨ãªããstaticã¡ã³ãã¼é¢æ°ã§ã¯ãªãã¡ã³ãã¼é¢æ°ã®ãã¨ããéstaticã¡ã³ãã¼é¢æ°ã¨ããããã ããfriendæå®åã¨å
±ã«å®£è¨ãããé¢æ°ã¯ãã¡ã³ãã¼é¢æ°ã§ã¯ãªãã
struct S
{
void non_static_member_function() ; // éstaticã¡ã³ãã¼é¢æ°
static void static_member_function() ; // staticã¡ã³ãã¼é¢æ°
friend void friend_function() ; // ããã¯ã¡ã³ãã¼é¢æ°ã§ã¯ãªã
} ;
ã¡ã³ãã¼é¢æ°ã¯ãã¯ã©ã¹å®ç¾©ã®å
å´ã§ãå¤å´ã§ãå®ç¾©ãããã¨ãã§ãããã¯ã©ã¹å®ç¾©ã®å
å´ã§å®ç¾©ãããã¡ã³ãã¼é¢æ°ããinlineã¡ã³ãã¼é¢æ°ã¨ãããããã¯ãæé»çã«inlineé¢æ°ã¨ãªããã¯ã©ã¹å®ç¾©ã®å¤å´ã§ã¡ã³ãã¼é¢æ°ãå®ç¾©ããå ´åãã¯ã©ã¹ã¨åãåå空éã¹ã³ã¼ãå
ã§å®ç¾©ããªããã°ãªããªãã
struct S
{
// inlineã¡ã³ãã¼é¢æ°
void inline_member_function()
{ /*å®ç¾©*/ }
void member_function() ; // ã¡ã³ãã¼é¢æ°ã®å®£è¨
} ;
// ã¯ã©ã¹Sã¨åãåå空éã¹ã³ã¼ã
void S::member_function()
{ /*å®ç¾©*/ }
ã¯ã©ã¹å®ç¾©ã®å¤å´ã§inlineã¡ã³ãã¼é¢æ°ã®å®ç¾©ããããã¨ãã§ãããããã«ã¯ãé¢æ°å®£è¨ãé¢æ°å®ç¾©ã§ãinlineæå®åã使ãã°ããã
struct S
{
inline void f() ;
void g() ;
} ;
void S::f(){ }
inline void S::g() { }
ã¯ã©ã¹å®ç¾©ã®å¤å´ã§ã¡ã³ãã¼é¢æ°ãå®ç¾©ããããã«ã¯ãã¡ã³ãã¼é¢æ°ã®ååãã::æ¼ç®åã«ãã£ã¦ãã¯ã©ã¹åã§ä¿®é£¾ããªããã°ãªããªãã
struct S
{
void member() ;
} ;
void S::member(){ }
ãã¼ã«ã«ã¯ã©ã¹ã§ã¯ãã¡ã³ãã¼é¢æ°ãã¯ã©ã¹å®ç¾©ã®å¤å´ã§å®£è¨ããæ¹æ³ã¯ãªãã
éstaticã¡ã³ãã¼é¢æ°ã¯ããã®ã¡ã³ãã¼é¢æ°ãå±ããã¯ã©ã¹ãããã®ã¯ã©ã¹ããæ´¾çãããã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã«å¯¾ãã¦ãã¯ã©ã¹ã¡ã³ãã¼ã¢ã¯ã»ã¹æ¼ç®åã使ããã¨ã§ãå¼ã³åºããã¨ãã§ãããåãã¯ã©ã¹ãããã®ã¯ã©ã¹ããæ´¾çãããã¯ã©ã¹ã®ã¡ã³ãã¼é¢æ°ããã¯ãä»ã®ã¡ã³ãã¼é¢æ°ããé常ã®é¢æ°ã®å¼ã³åºãã¨åãããã«å¼ã¶ãã¨ãã§ããã
struct Object
{
void f(){ }
void g()
{
// é¢æ°å¼ã³åºã
f() ;
}
} ;
int main()
{
Object object ;
// ã¯ã©ã¹ã®ã¡ã³ãã¼ã¢ã¯ã»ã¹æ¼ç®åã¨ãé¢æ°å¼ã³åºã
object.f() ;
}
éstaticã¡ã³ãã¼é¢æ°ã¯ãCV修飾åã¨å
±ã«å®£è¨ãããã¨ãã§ããã
struct S
{
void none() ;
void c() const ; // constã¡ã³ãã¼é¢æ°
void v() volatile ; // volatileã¡ã³ãã¼é¢æ°
void cv() const volatile ; // const volatileã¡ã³ãã¼é¢æ°
} ;
ãã®CV修飾åã¯ãthisãã¤ã³ã¿ã¼ã®åãå¤ãããã¾ããã¡ã³ãã¼é¢æ°ã®åããCV修飾åã«å½±é¿ãããã
éstaticã¡ã³ãã¼é¢æ°ã¯ããªãã¡ã¬ã³ã¹ä¿®é£¾åã¨å
±ã«å®£è¨ãããã¨ãã§ããããªãã¡ã¬ã³ã¹ä¿®é£¾åã¯ããªã¼ãã¼ãã¼ã解決ã®éã®ãæé»ã®ä»®å¼æ°ã®åã«å½±é¿ãä¸ããã詳ããã¯ãåè£é¢æ°ã¨å®å¼æ°ãªã¹ããåç
§ã
éstaticã¡ã³ãã¼é¢æ°ã¯ãvirtualããã¥ã¢virtualã®ææ³ã§å®£è¨ãããã¨ãã§ããã詳ããã¯ãvirtualé¢æ°ããæ½è±¡ã¯ã©ã¹ãåç
§ã
éstaticã¡ã³ãã¼é¢æ°å
ã§ã¯ãthisã¨ãããã¼ã¯ã¼ãããã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã¸ã®prvalueã®ãã¤ã³ã¿ã¼ã表ãããã®ã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã¯ãã¡ã³ãã¼é¢æ°ãå¼ã³åºããéã®ã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã§ããã
struct Object
{
void f()
{
this ;
}
} ;
int main()
{
Object a, b, c ;
a.f() ; // thisã¯&a
b.f() ; // thisã¯&b
c.f() ; // thisã¯&c
}
class Xã®ã¡ã³ãã¼é¢æ°ã«ãããthisã®åã¯ãX *ã§ããããããconstã¡ã³ãã¼é¢æ°ã®å ´åãX const *ã¨ãªããvolatileã¡ã³ãã¼é¢æ°ã®å ´åãX volatile *ã¨ãªããconst volatileã¡ã³ãã¼é¢æ°ã®å ´åã¯ãX const volatile *ã¨ãªãã
class X
{
// thisã®åã¯X *
void f() { this ; }
// thisã®åã¯X const *
void f() const { this ; }
// thisã®åã¯X volatile *
void f() volatile { this ; }
// thisã®åã¯X const volatile *
void f() const volatile { this ; }
} ;
constã¡ã³ãã¼é¢æ°ã§ã¯ãã¡ã³ãã¼é¢æ°ã«æ¸¡ãããã¯ã©ã¹ã®ãªãã¸ã§ã¯ããconstã§ãããããthisã®åããconstãªã¯ã©ã¹ã¸ã®ãã¤ã³ã¿ã¼åã¨ãªããéstaticãã¼ã¿ã¡ã³ãã¼ãå¤æ´ãããã¨ãã§ããªãã
class X
{
int value ;
void f() const
{
this->value = 0 ; // ã¨ã©ã¼
}
} ;
ããã¯ãthisã®åãèãã¦ã¿ãã¨åãããããã
class X
{
int value ;
void f() const
{
X const * ptr = this ;
ptr->value = 0 ; // ã¨ã©ã¼
}
} ;
thisã®åããconstãªã¯ã©ã¹ã«å¯¾ãããã¤ã³ã¿ã¼ãªã®ã§ããã¼ã¿ã¡ã³ãã¼ãå¤æ´ãããã¨ã¯ã§ããªãã
åæ§ã«ãã¦ãvolatileã®å ´åããéstaticãã¼ã¿ã¡ã³ãã¼ã¯volatileæå®ããããã®ã¨ã¿ãªããããvolatileã®å
·ä½çãªæ©è½ã¤ãã¦ã¯ãå®è£
ã«ä¾åããã
CV修飾ãããã¡ã³ãã¼é¢æ°ã¯ãåçããããå°ãªãCV修飾ãããã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã«å¯¾ãã¦å¼ã³åºããã¨ãã§ããã
struct X
{
X() { }
void f() const { } ;
} ;
int main()
{
X none ;
none.f() ; // OKãããå°ãªãCV修飾ããã¦ãã
X const c ;
c.f() ; // OKãåãCV修飾
X const volatile cv ;
cv.f() ; // ã¨ã©ã¼ãCV修飾åãåãé¤ããã¨ã¯ã§ããªã
}
ããã¯ãéstaticã¡ã³ãã¼é¢æ°ãããä»ã®éstaticã¡ã³ãã¼é¢æ°ããã¯ã©ã¹ã¡ã³ãã¼ã¢ã¯ã»ã¹ãªãã§å¼ã³åºãéã«ãå½ã¦ã¯ã¾ãããã®å ´åãã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã¨ã¯ãthisã§ããã
struct X
{
void c() const // constã¡ã³ãã¼é¢æ°
{
// thisã®åã¯X const *
nc() ; // ã¨ã©ã¼ãCV修飾åãåãé¤ããã¨ã¯ã§ããªã
} ;
void nc() // éconstã¡ã³ãã¼é¢æ°
{
// thisã®åã¯X *
c() ; // OKãCV修飾åãä»ãå ãããã¨ã¯ã§ãã
}
} ;
ã³ã³ã¹ãã©ã¯ã¿ã¼ã¨ãã¹ãã©ã¯ã¿ã¼ã¯ãCV修飾åã¨å
±ã«å®£è¨ãããã¨ãã§ããªãããã ãããããã®ç¹å¥ãªã¡ã³ãã¼é¢æ°ã¯ãconstãªã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã®çæãç ´æ£ã®éã«ããå¼ã³åºãããã
ã¯ã©ã¹ã®ãã¼ã¿ã¡ã³ãã¼ãã¡ã³ãã¼é¢æ°ã¯ãã¯ã©ã¹å®ç¾©å
ã§ãstaticæå®åã¨å
±ã«å®£è¨ãããã¨ãåºæ¥ãããã®ããã«å®£è¨ãããã¡ã³ãã¼ããã¯ã©ã¹ã®staticã¡ã³ãã¼ã¨ããã
struct S
{
static int data_member ;
static void member_function() ;
} ;
int S::data_member ;
ã¯ã©ã¹Xã®staticã¡ã³ãã¼sã¯ã::æ¼ç®åãç¨ãã¦ãX::sã®ããã«åç
§ãããã¨ã§ã使ããã¨ãã§ãããstaticã¡ã³ãã¼ã¯ãã¯ã©ã¹ã®ãªãã¸ã§ã¯ãããªãã¦ãåç
§ã§ããã®ã§ãã¯ã©ã¹ã®ã¡ã³ãã¼ã¢ã¯ã»ã¹æ¼ç®åã使ãå¿
è¦ã¯ãªããããããã¯ã©ã¹ã®ã¡ã³ãã¼ã¢ã¯ã»ã¹æ¼ç®åã使ã£ã¦ãåç
§ã§ããã
struct X
{
static int s ;
} ;
int X::s ;
int main()
{
// ::æ¼ç®åã«ããåç
§
X::s ;
// ã¯ã©ã¹ã®ã¡ã³ãã¼ã¢ã¯ã»ã¹æ¼ç®åã§ãåç
§ãããã¨ã¯ã§ãã
X object ;
object.s ;
}
ã¯ã©ã¹ã®ã¡ã³ãã¼é¢æ°å
ã§ã¯ãé修飾åã使ã£ãå ´åãã¯ã©ã¹ã®staticã¡ã³ãã¼ãenumåããã¹ããããåãååæ¢ç´¢ãããã
struct X
{
void f()
{
s ; // X::s
value ; // X::value
type obj ; // X::type
}
static int s ;
enum { value } ;
typedef int type ;
} ;
int X::s ;
staticã¡ã³ãã¼ã«ããé常éãã®ã¢ã¯ã»ã¹æå®ãé©ç¨ãããã
staticã¡ã³ãã¼é¢æ°ã¯ãthisãã¤ã³ã¿ã¼ãæããªããvirtualæå®åã使ããªããCV修飾åã使ããªããååã¨ä»®å¼æ°ã®åããstaticã¡ã³ãã¼é¢æ°ã¨éstaticã¡ã³ãã¼é¢æ°ã¯ã両ç«ã§ããªãã
struct S
{
// ã¨ã©ã¼ãåãååã¨ä»®å¼æ°ã®staticé¢æ°ã¨éstaticé¢æ°ãåå¨ãã
void same() ;
static void same() ;
} ;
ãã®ä»ã¯ãé常ã®ã¡ã³ãã¼é¢æ°ã¨åãã§ããã
staticãã¼ã¿ã¡ã³ãã¼ã¯ãã¯ã©ã¹ã®ãµããªãã¸ã§ã¯ãã«ã¯å«ã¾ããªããstaticãã¼ã¿ã¡ã³ãã¼ã¯ãã¯ã©ã¹ã®ã¹ã³ã¼ãã§ã¢ã¯ã»ã¹å¯è½ãªstaticå¤æ°ã ã¨èãã¦ããããã¯ã©ã¹ã®ãã¹ã¦ã®ãªãã¸ã§ã¯ãã¯ãã²ã¨ã¤ã®staticãã¼ã¿ã¡ã³ãã¼ã®ãªãã¸ã§ã¯ããå
±æããããã ããstatic thread_localãªãã¼ã¿ã¡ã³ãã¼ã®ãªãã¸ã§ã¯ãã¯ãã¹ã¬ããã«ã¤ãã²ã¨ã¤åå¨ããã
struct S
{
static int member ;
} ;
int S::member ;
int main()
{
S a, b, c, d, e ;
// ãã¹ã¦åããªãã¸ã§ã¯ããåç
§ãã
a.member ; b.member ; c.member ; e.member ;
}
ã¯ã©ã¹å®ç¾©å
ã®staticãã¼ã¿ã¡ã³ãã¼å®£è¨ã¯ãå®ç¾©ã§ã¯ãªããstaticãã¼ã¿ã¡ã³ãã¼ã®å®ç¾©ã¯ãã¯ã©ã¹ã®å®ç¾©ãå«ãåå空éã¹ã³ã¼ãã®ä¸ã«æ¸ããªããã°ãªããªãããã®éãååã«::æ¼ç®åãç¨ãã¦ãã¯ã©ã¹åãæå®ããå¿
è¦ããããstaticãã¼ã¿ã¡ã³ãã¼ã®å®ç¾©ã«ã¯ãåæååã使ããã¨ãã§ãããåæååã¯å¿
é ã§ã¯ãªãã
struct S
{
static int member ;
} ;
// ã¯ã©ã¹å :: ã¡ã³ãã¼å
int S::member = 0 ;
staticãã¼ã¿ã¡ã³ãã¼ããconstãªãªãã©ã«åã®å ´åãã¯ã©ã¹å®ç¾©å
ã®å®£è¨ã«ãåæååãæ¸ããã¨ãã§ããããã®å ´åãåæååã¯å®æ°å¼ã§ãªããã°ãªããªããstaticãã¼ã¿ã¡ã³ãã¼èªä½ããå®æ°å¼ã«ãªããåæååãæ¸ããªãå ´åã¯ãé常éããã¯ã©ã¹å®ç¾©ã®å¤ãåãåå空éã¹ã³ã¼ãå
ã§ãå®ç¾©ãæ¸ããªããã°ãªããªãããã®å ´åã¯ãå®æ°å¼ã«ã¯ãªããªãã
struct S
{
static const int constant_expression = 123 ; // å®æ°å¼
static const int non_constant_expression ; // 宣è¨ãå®æ°å¼ã§ã¯ãªã
} ;
const int S::non_constant_expression = 123 ; // å®ç¾©
ãªãã©ã«åã®staticãã¼ã¿ã¡ã³ãã¼ã¯ãconstexpræå®åãã¤ãã¦å®£è¨ãããã¨ãã§ããããã®å ´åãåæååãæ¸ããªããã°ãªããªããåæååã¯ãå®æ°å¼ã§ãªããã°ãªããªãããã®ããã«å®ç¾©ãããstaticãã¼ã¿ã¡ã³ãã¼ã¯ãå®æ°å¼ã«ãªãã
struct S
{
static constexpr int constant_expression = 123 ; // å®æ°å¼
} ;
åå空éã¹ã³ã¼ãã®ã¯ã©ã¹ã®staticãã¼ã¿ã¡ã³ãã¼ã¯ãå¤é¨ãªã³ã±ã¼ã¸ãæã¤ããã¼ã«ã«ã¯ã©ã¹ã®staticãã¼ã¿ã¡ã³ãã¼ã¯ããªã³ã±ã¼ã¸ãæããªãã
staticãã¼ã¿ã¡ã³ãã¼ã¯ãéãã¼ã«ã«å¤æ°ã¨åãããã«ãåæåãç ´æ£ãããã詳ããã¯ãéãã¼ã«ã«å¤æ°ã®åæåãçµäºãåç
§ã
staticãã¼ã¿ã¡ã³ãã¼ã«ã¯ãmutableæå®åã¯ä½¿ããªãã
unionã¨ããã¯ã©ã¹ã¯ãã¯ã©ã¹ãã¼ã«unionãã¼ã¯ã¼ããç¨ãã¦å®£è¨ãããunionã§ã¯ãéstaticãã¼ã¿ã¡ã³ãã¼ã¯ãã©ããã²ã¨ã¤ã®ã¿ãæå¹ã§ãããããã¯ãunionã®ãªãã¸ã§ã¯ãå
ã§ã¯ãéstaticãã¼ã¿ã¡ã³ãã¼ã®ã¹ãã¬ã¼ã¸ã¯ãå
±æããã¦ããããã§ãããunionã®ãµã¤ãºã¯ãéstaticãã¼ã¿ã¡ã³ãã¼ã®ãã¡ãæã大ããªåãæ ¼ç´ããã®ã«ååãªãµã¤ãºã¨ãªãã
union U
{
int i ;
short s ;
double d ;
} ;
int main()
{
U u ;
u.i = 0 ; // U::iãæå¹
u.s = 0 ; // U::sãæå¹ãU::iã¯æå¹ã§ã¯ãªããªã
}
ãã®ä¾ã§ã¯ãunionã®ãµã¤ãºã¯ãint, short, doubleã®ãã¡ã®ãæããµã¤ãºã大ããªåãæ ¼ç´ããã®ã«ååãªã ãã®ãµã¤ãºã§ããããã¼ã¿ã¡ã³ãã¼ã§ããi, s, dã¯ãåãã¹ãã¬ã¼ã¸ãå
±æãã¦ããã
unionã¨ãæ¨æºã¬ã¤ã¢ã¦ãã¯ã©ã¹ã«ã¤ãã¦ã¯ãã¯ã©ã¹ãåç
§ã
unionã¯ãé常ã®ã¯ã©ã¹ã«æ¯ã¹ã¦ãããããå¶éãåãããunionã¯virtualé¢æ°ãæã¤ãã¨ãã§ããªããunionã¯ãåºæ¬ã¯ã©ã¹ãæã¤ãã¨ãã§ããªããunionã¯åºæ¬ã¯ã©ã¹ã«ãªããªããunionã¯ããªãã¡ã¬ã³ã¹åã®éstaticãã¼ã¿ã¡ã³ãã¼ãæã¤ãã¨ãã§ããªããunionã®éstaticãã¼ã¿ã¡ã³ãã¼ã®ãã¡ãåæååãæã¦ãã®ã¯ãã²ã¨ã¤ã ãã§ããã
// ã¨ã©ã¼ã®ä¾
// ã¨ã©ã¼ãvirtualé¢æ°ãæã¦ãªã
union U1 { virtual void f() { } } ;
// ã¨ã©ã¼ãåºæ¬ã¯ã©ã¹ãæã¦ãªã
struct Base { } ;
union U : Base { } ;
// ã¨ã©ã¼ãåºæ¬ã¯ã©ã¹ã«ãªããªã
union Union_base { } ;
union Derived : Union_base { } ;
// ã¨ã©ã¼ããªãã¡ã¬ã³ã¹åã®éstaticãã¼ã¿ã¡ã³ãã¼ãæã¦ãªã
union U2 { int & ref ; } ;
// ã¨ã©ã¼ãéstaticãã¼ã¿ã¡ã³ãã¼ã§ãåæååãæã¦ãã®ã¯ãã²ã¨ã¤ã ã
union U3
{
int x = 0 ;
int y = 0 ; // ã¨ã©ã¼ãè¤æ°ã®åæååãã©ã¡ããä¸ã¤ãªãã¨ã©ã¼ã§ã¯ãªã
} ;
ãã®ä»ã¯ãé常ã®ã¯ã©ã¹ã¨å¤ãããã¨ããªããunionã¯ã¡ã³ãã¼é¢æ°ãæã¦ããã¡ã³ãã¼é¢æ°ã«ã¯ãã³ã³ã¹ãã©ã¯ã¿ã¼ããã¹ãã©ã¯ã¿ã¼ãæ¼ç®åã®ãªã¼ãã¼ãã¼ããå«ã¾ãããã¢ã¯ã»ã¹æå®ã使ãããstaticãã¼ã¿ã¡ã³ãã¼ãªãã°ããªãã¡ã¬ã³ã¹åã§ãæ§ããªãããã¹ããããåã使ããã
unionã®éstaticãã¼ã¿ã¡ã³ãã¼ããétrivialãªã³ã³ã¹ãã©ã¯ã¿ã¼ãã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ãã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ãã³ãã¼ä»£å
¥æ¼ç®åãã ã¼ã代å
¥æ¼ç®åããã¹ãã©ã¯ã¿ã¼ãæã£ã¦ããå ´åãunionã®å¯¾å¿ããã¡ã³ãã¼ããæé»çã«deleteãããããã®ããããããã®ã¡ã³ãã¼ã使ãå ´åã«ã¯ãunionå´ã§ãã¦ã¼ã¶ã¼å®ç¾©ããªããã°ãªããªãã
union U
{
std::string str ;
std::vector<int> vec ;
} ;
int main()
{
U u ; // ã¨ã©ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¨ãã¹ãã©ã¯ã¿ã¼ãdeleteå®ç¾©ããã¦ããã
}
ãã®ä¾ã§ã¯ãstrãvecã¯ãétrivialãªã³ã³ã¹ãã©ã¯ã¿ã¼ããã¹ãã©ã¯ã¿ã¼ãªã©ãæã£ã¦ããã®ã§ãunionå´ã§ããããããå®ç¾©ããªããã°ãªããªããã¾ãããã®ä¾ã®å ´åãunionã®ã³ã³ã¹ãã©ã¯ã¿ã¼ããã¹ãã©ã¯ã¿ã¼ã¯ä½ãããªãã®ã§ããã®unionãå®éã«ä½¿ãå ´åã«ã¯ãplacement newããæ示çãªãã¹ãã©ã¯ã¿ã¼å¼ã³åºããå¿
è¦ã«ãªãã
union U
{
std::string str ;
std::vector<int> vec ;
U() { }
~U() { }
} ;
int main()
{
U u ;
new ( &u.str ) std::string( "hello" ) ;
u.str.~basic_string() ;
new ( &u.vec ) std::vector<int> { 1, 2, 3 } ;
u.vec.~vector() ;
}
ãã¡ãããunionã®ã³ã³ã¹ãã©ã¯ã¿ã¼ããã¹ãã©ã¯ã¿ã¼ã§ãã©ããã®ãã¼ã¿ã¡ã³ãã¼ã®åæåãç ´æ£ããããã¨ã¯å¯è½ã§ãããããããã©ã®ãã¼ã¿ã¡ã³ãã¼ãæå¹ãªã®ãã¨ãããã¨ããunionå
ã§ææ¡ããã®ã¯é£ããã
以ä¸ã®ãããªå½¢å¼ã®unionã®å®£è¨ããç¡åunionï¼anonymous unionï¼ã¨ããã
union { ã¡ã³ãã¼æå®opt } ;
ç¡åunionã¯ãç¡åã®åã®unionã®ãç¡åã®ãªãã¸ã§ã¯ããçæãããç¡åunionã®ã¡ã³ãã¼æå®ã¯ãéstaticãã¼ã¿ã¡ã³ãã¼ã ãã§ãªããã°ãªããªããç¡åunionã®ã¡ã³ãã¼ã®ååã¯ã宣è¨ããã¦ããã¹ã³ã¼ãã®ä»ã®ååã¨è¡çªãã¦ã¯ãªããªããç¡åunionã§ã¯ãstaticãã¼ã¿ã¡ã³ãã¼ãã¡ã³ãã¼é¢æ°ããã¹ããããåãªã©ã¯ä½¿ããªããã¾ããprivateãprotectedã¢ã¯ã»ã¹æå®ã使ããªãã
int main()
{
union { int i ; short s ; } ;
// iãsã®ã©ã¡ããã²ã¨ã¤ã ããæå¹
i = 0 ;
s = 0 ;
}
ããã¯ã以ä¸ã®ãããªã³ã¼ãã¨åãã§ããã¨èãããã¨ãã§ããã
int main()
{
union Anonymous { int i ; short s ; } unnamed ;
unnamed.i = 0 ;
unnamed.s = 0 ;
}
åå空éã¹ã³ã¼ãã§å®£è¨ãããç¡åunionã«ã¯ãå¿
ãstaticæå®åãã¤ããªããã°ãªããªãã
// ã°ãã¼ãã«åå空éã¹ã³ã¼ã
static union { int x ; int y ; } ;
åå空éã¹ã³ã¼ãã§å®£è¨ãããç¡åunionã¯ãstaticã¹ãã¬ã¼ã¸ã®æå¹æéã¨ãå
é¨ãªã³ã±ã¼ã¸ãæã¤ã
ãããã¯ã¹ã³ã¼ãã§å®£è¨ãããç¡åunionã¯ããããã¯ã¹ã³ã¼ãå
ã§è¨±ããã¦ãããã¹ã¦ã®ã¹ãã¬ã¼ã¸ä¸ã«æ§ç¯ã§ããã
int main()
{
// èªåã¹ãã¬ã¼ã¸
union { int a } ;
// staticã¹ãã¬ã¼ã¸
static union { int b } ;
// thread_localã¹ãã¬ã¼ã¸
thread_local union { int c } ;
}
ã¯ã©ã¹ã¹ã³ã¼ãã§å®£è¨ãããç¡åunionã«ã¯ãã¹ãã¬ã¼ã¸æå®åãä»ãããã¨ã¯ã§ããªãã
struct S
{
union
{
int x ;
} ;
} ;
ãªãã¸ã§ã¯ãããã¤ã³ã¿ã¼ã宣è¨ãã¦ãããã¯ã©ã¹åã®çç¥ãããunionã¯ãç¡åunionã§ã¯ãªãã
// ã¯ã©ã¹åã®çç¥ãããunion
// ç¡åunionã§ã¯ãªã
union { int x ; } obj, * ptr ;
unionããããã¯ç¡åunionãç´æ¥ã®ã¡ã³ãã¼ã«æã¤ã¯ã©ã¹ããunionã®ãããªã¯ã©ã¹ï¼union-like classï¼ã¨ãããunionã®ãããªã¯ã©ã¹ã«ã¯ãå
±ç¨ã¡ã³ãã¼ï¼variant memberï¼ã¨ããæ¦å¿µãåå¨ãããunionã®å
±ç¨ã¡ã³ãã¼ã¯ãunionã®éstaticãã¼ã¿ã¡ã³ãã¼ã§ãããç¡åunionãç´æ¥ã®ã¡ã³ãã¼ã«æã¤ã¯ã©ã¹ã®å ´åãç¡åunionã®éstaticãã¼ã¿ã¡ã³ãã¼ã§ããã
// xã¨yã¯å
±ç¨ã¡ã³ãã¼
union U { int x ; int y ; }
// xã¨yã¯å
±ç¨ã¡ã³ãã¼
struct S
{
union { int x ; int y ; } ;
} ;
ããããã£ã¼ã«ãã¯ã以ä¸ã®ãããªã¡ã³ãã¼å®£è¨åã®ææ³ã§å®£è¨ã§ããã
èå¥åopt : å®æ°å¼
å®æ°å¼ã¯ã0ããã大ããæ´æ°ã§ãªããã°ãªããªãã
struct S
{
int // åæå®å
x : 8 ; // ããããã£ã¼ã«ãã®å®£è¨å
} ;
ããããã£ã¼ã«ãã®å®æ°å¼ã¯ããã¼ã¿ã¡ã³ãã¼ã®ãµã¤ãºããããæ°ã§æå®ãããããããã£ã¼ã«ãã«é¢ãã¦ã¯ãã»ã¨ãã©ã®æåãå®è£
ä¾åã§ãããç¹ã«ãããããã£ã¼ã«ããã¯ã©ã¹ãªãã¸ã§ã¯ãã®ã¹ãã¬ã¼ã¸ä¸ã§ã©ã®ããã«è¡¨ç¾ãããã®ãã¨ãããã¨ããã¢ã©ã¤ã¡ã³ããªã©ã¯ããã¹ã¦å®è£
ä¾åã§ãããã¾ããå®è£
ã¯ãããããã£ã¼ã«ãã®ã¡ã³ãã¼å士ãè©°ãã¦è¡¨ç¾ãããã¨ã許ããã¦ããã
struct S
{
char x : 1 ;
char y : 1 ;
} ;
ããã§ãsizeof(S)ã¯ã2以ä¸ã«ãªãã¨ã¯éããªããä¾ãã°ãsizeof(S)ã1ãè¿ãå®è£
ãããå¾ãã
ããããã£ã¼ã«ãã®å®æ°å¼ã¯ããªãã¸ã§ã¯ãã®ãããæ°ãä¸åããã¨ãã§ããããã®å ´åãä¸åã£ããããæ°ã¯ãããã£ã³ã°ã¨ãã¦ç¢ºä¿ããããããªãã¸ã§ã¯ãã®å
é¨è¡¨ç¾ã¨ãã¦ä½¿ããããã¨ã¯ãªãã
struct S
{
int x : 1000 ;
} ;
ããã§ãsizeof(S)ã¯ãå°ãªãã¨ã1000ããã以ä¸ã«ãªãå¤ãè¿ãï¼è¦æ ¼ã§ã¯ã1ãã¤ããããã®ãããæ°ã¯å®ãããã¦ããªãï¼ããã ããS::xã¯ãæ¬æ¥ã®intå以ä¸ã®ç¯å²ã®å¤ãä¿æãããã¨ã¯ã§ããªããintåã®ãªãã¸ã§ã¯ãã®ãããæ°ãä¸åã£ãåã¯ãåã«ããã£ã³ã°ã¨ãã¦ç¢ºä¿ããã¦ããã«éããªãã
ããããã£ã¼ã«ãã®å®£è¨åã§ãèå¥åãçç¥ããå ´åãç¡åããããã£ã¼ã«ãã¨ãªããç¡åããããã£ã¼ã«ãã¯ã¯ã©ã¹ã®ã¡ã³ãã¼ã§ã¯ãªããåæåããããªãããã ããå®è£
ä¾åã®æ¹æ³ã§ãã¯ã©ã¹ã®ãªãã¸ã§ã¯ãå
ã«åå¨ãããä¸è¬çãªå®è£
ã§ã¯ãç¡åããããã£ã¼ã«ãã¯ããªãã¸ã§ã¯ãã®ã¬ã¤ã¢ã¦ãã調æ´ããããã®ããã£ã³ã°ã¨ãã¦ç¨ããããã
struct S
{
int x : 4 ;
char : 3 ; // ç¡åããããã£ã¼ã«ã
int y : 1 ;
} ;
ããã³ã³ãã¤ã©ã¼ã§ã¯ããã®ãããªç¡åããããã£ã¼ã«ãã«ãããS::xã¨S::yã®éã«ã3ãããåã®ããã£ã³ã°ãæ¿å
¥ãããã¨ãã§ããããã ãããã§ã«è¿°ã¹ãããã«ãããããã£ã¼ã«ãã®å
é¨è¡¨ç¾ã¨ã¢ã©ã¤ã¡ã³ãã¯å®è£
ä¾åãªã®ã§ãããã¯ãã¹ã¦ã®ã³ã³ãã¤ã©ã¼ã«å½ã¦ã¯ã¾ãããã§ã¯ãªãã使ç¨ãã¦ããã³ã³ãã¤ã©ã¼ããããããã£ã¼ã«ããã©ã®ããã«å®è£
ãã¦ãããã¯ãã³ã³ãã¤ã©ã¼ç¬èªã®ããã¥ã¢ã«ãåç
§ãã¹ãã§ããã
ç¡åããããã£ã¼ã«ãã§ã¯ãç¹å¥ã«ãå®æ°å¼ã«0ãæå®ãããã¨ãã§ããã
struct S
{
int x : 4 ;
char : 0 ; // ç¡åããããã£ã¼ã«ã
int y : 4 ;
} ;
ããã¯ãç¡åããããã£ã¼ã«ãã®æ¬¡ã®ããããã£ã¼ã«ãã®ã¢ã©ã¤ã¡ã³ãããã¢ãã±ã¼ã·ã§ã³åä½ã®å¢çã«é
ç½®ãããããã®æå®ã§ãããä¸è¨ã®æ§é ä½ã¯ãããç°å¢ã§ã¯ãS::xã¨S::yãåä¸ã®ã¢ãã±ã¼ã·ã§ã³åä½ã«é
ç½®ããããããããªãããç¡åããããã£ã¼ã«ãã使ããã¨ã§ãX::yãå¥ã®ã¢ãã±ã¼ã·ã§ã³åä½ã«é
ç½®ã§ããã
ããããã£ã¼ã«ãã¯staticã¡ã³ãã¼ã«ã¯ã§ããªããããããã£ã¼ã«ãã®åã¯ãæ´æ°åãenumåã§ãªããã°ãªããªãã符å·ãæå®ããã¦ããªãæ´æ°åã®ããããã£ã¼ã«ãã®ç¬¦å·ã¯å®è£
ä¾åã§ããã
struct S
{
static int error : 8 ; // ã¨ã©ã¼ãããããã£ã¼ã«ãã¯staticã¡ã³ãã¼ã«ã¯ã§ããªã
int impl : 8 ; // 符å·ã¯å®è£
ä¾å
signed s : 8 ; // 符å·ã¯signed
unsigned u : 8 ; // 符å·ã¯unsigned
} ;
boolåã®ããããã£ã¼ã«ãã¯ããããæ°ã«é¢ããããboolåã®å¤ã表ç¾ã§ããã
struct S
{
bool a : 1 ;
bool b : 2 ;
bool c : 3 ;
} ;
int main()
{
S s ;
s.a = true ;
s.b = false ;
s.c = true ;
}
ããããã£ã¼ã«ãã®ã¢ãã¬ã¹ãå¾ããã¨ã¯ã§ããªããã¤ã¾ãã&æ¼ç®åãããããã£ã¼ã«ãã«é©ç¨ãããã¨ã¯ã§ããªãã
struct S
{
int x : 8 ;
} ;
int main()
{
S s ;
&s.x ; // ã¨ã©ã¼
}
ãªãã¡ã¬ã³ã¹ã¯ãããããã£ã¼ã«ããåç
§ãããã¨ã¯ã§ããªãããã ããconstãªlvalueãªãã¡ã¬ã³ã¹ã®åæååããlvalueã®ããããã£ã¼ã«ãã®å ´åã¯ãä¸æãªãã¸ã§ã¯ããçæããããã®ãªãã¸ã§ã¯ããåç
§ããã
struct S
{
int x : 8 ;
} ;
int main()
{
S s ;
// ã¨ã©ã¼
int & ref = s.x ;
// OK
// ãã ããcrefãåç
§ããã®ã¯ãçæãããä¸æãªãã¸ã§ã¯ãã§ãã
// s.xã§ã¯ãªã
int const & cref = s.x ;
}
ã¯ã©ã¹ã¯ãä»ã®ã¯ã©ã¹ã®å
å´ã§å®£è¨ãããã¨ãã§ããããããããã¹ããããã¯ã©ã¹ï¼nested classï¼ã¨ããã
class Outer
{
class Inner { } ; // ãã¹ããããã¯ã©ã¹
} ;
int main()
{
Outer::Inner object ;
}
ãã¹ããããã¯ã©ã¹ã®ã¹ã³ã¼ãã¯ãå¤å´ã®ã¯ã©ã¹ã®ã¹ã³ã¼ãã«å¾ããããã¯ãååæ¢ç´¢ã®éããå¤å´ã®ã¯ã©ã¹ã®ã¹ã³ã¼ããå½±é¿ããã¨ãããã¨ã§ããã
int x ; // ã°ãã¼ãã«å¤æ°
struct Outer
{
int x ; // Outer::x
struct Inner
{
void f()
{
sizeof(x) ; // OKãsizeofã®ãªãã©ã³ãã¯æªè©ä¾¡å¼ãOuter::xã®ãµã¤ãºãè¿ã
x = 0 ; // ã¨ã©ã¼ãOuter::xã¯Outerã®éstaticã¡ã³ãã¼
::x = 0 ; // OKãã°ãã¼ãã«å¤æ°
}
} ;
} ;
é¢æ°Inner::fã®ä¸ã§ãxã¨ããååã使ãã¨ãOuter::xãè¦ã¤ãããããã¯ãã¯ã©ã¹Innerããã¯ã©ã¹Outerã®ã¹ã³ã¼ãå
ã«ããããã§ãããããããéstaticãã¼ã¿ã¡ã³ãã¼ã§ããOuter::xã使ãããã«ã¯ãOuterã®ãªãã¸ã§ã¯ããå¿
è¦ãªã®ã§ãããã§ã¯ã¨ã©ã¼ã¨ãªããsizeofã®ãªãã©ã³ãã¯æªè©ä¾¡å¼ãªã®ã§ãåé¡ã¯ãªãããã ããããã§ã®xã¯ãOuter::xã§ãããã°ãã¼ãã«å¤æ°ã®xã§ã¯ãªãã
ãã¹ããããã¯ã©ã¹ã®ã¡ã³ãã¼é¢æ°ãstaticãã¼ã¿ã¡ã³ãã¼ã¯ãé常ã®ã¯ã©ã¹éããã¯ã©ã¹å®ç¾©ã®å¤å´ãåãåå空éå
ã§å®ç¾©ãããã¨ãã§ããã
// ã°ãã¼ãã«åå空é
struct Outer
{
struct Inner
{
static int x ;
void f() ;
} ;
} ;
// åãåå空éå
int Outer::Inner::x = 0 ;
void Outer::Inner::f() { }
ã¾ãé常éããã¯ã©ã¹ã®å®£è¨ã ãããã¦ãå®ç¾©ãå¾ã§æ¸ããã¨ãã§ããã
struct Outer
{
class Inner ; // 宣è¨
} ;
class Outer::Inner { } ; // å®ç¾©
é¢æ°å®ç¾©ã®ä¸ã§ãã¯ã©ã¹ãå®ç¾©ãããã¨ãã§ãããããããã¼ã«ã«ã¯ã©ã¹ï¼local classï¼ã¨ããã
int main()
{ // é¢æ°å®ç¾©
class Local { } ; // ãã¼ã«ã«ã¯ã©ã¹
Local object ; // ãã¼ã«ã«ã¯ã©ã¹ã®ãªãã¸ã§ã¯ã
}
ãã¼ã«ã«ã¯ã©ã¹ã®ã¹ã³ã¼ãã¯ãã¯ã©ã¹å®ç¾©ã®å¤å´ã®ã¹ã³ã¼ãã§ãããã¾ããååæ¢ç´¢ã¯ããã¼ã«ã«ã¯ã©ã¹ãå®ç¾©ããã¦ããé¢æ°ã¨åãã¨ãªãã
ãã¼ã«ã«ã¯ã©ã¹ã¯ãå®ç¾©ããã¦ããé¢æ°å
ã®èªåå¤æ°ã使ããã¨ã¯åºæ¥ãªããtypedefåãstaticå¤æ°ãªã©ã¯ä½¿ããã
int main()
{
int x ; // ãã¼ã«ã«å¤æ°
typedef int type ;
static int y ;
class Local
{
void f()
{
x = 0 ; // ã¨ã©ã¼
// typedefåãstaticå¤æ°ãªã©ã¯ä½¿ãã
type val ; // OK
y = 0 ; // OK
// OKãsizeofã®ãªãã©ã³ãã¯æªè©ä¾¡å¼
sizeof(x) ;
}
} ;
}
ãã¼ã«ã«ã¯ã©ã¹ã¯ãé常ã®ã¯ã©ã¹ããå¶éãå¤ãããã¼ã«ã«ã¯ã©ã¹ããã³ãã¬ã¼ã宣è¨ãããã¨ã¯ã§ããªããã¡ã³ãã¼ãã³ãã¬ã¼ããæã¤ãã¨ãã§ããªãããã¼ã«ã«ã¯ã©ã¹ã®ã¡ã³ãã¼é¢æ°ã¯ãã¯ã©ã¹å®ç¾©å
ã§å®ç¾©ãããªããã°ãªããªãããã¼ã«ã«ã¯ã©ã¹ã®å¤å´ã§ã¡ã³ãã¼é¢æ°ãå®ç¾©ããæ¹æ³ã¯ãªããstaticãã¼ã¿ã¡ã³ãã¼ãæã¤ãã¨ã¯ã§ããªãã
int main()
{
// ã¨ã©ã¼ããã¼ã«ã«ã¯ã©ã¹ã¯ãã³ãã¬ã¼ã宣è¨ã§ããªã
template < typename T >
class Local
{
// ã¨ã©ã¼ããã¼ã«ã«ã¯ã©ã¹ã¯ã¡ã³ãã¼ãã³ãã¬ã¼ããæã¦ãªãã
template < typename U > void f() { }
// OKããã ãããã¼ã«ã«ã¯ã©ã¹ã®å¤å´ã§ã¡ã³ãã¼é¢æ°ãå®ç¾©ããæ¹æ³ã¯ãªã
void f() ;
// ã¨ã©ã¼ããã¼ã«ã«ã¯ã©ã¹ã¯staticãã¼ã¿ã¡ã³ãã¼ãæã¤ãã¨ã¯ã§ããªãã
static int x ;
} ;
}
ã¯ã©ã¹å
ã®ååãããã¹ããããååï¼nested type nameï¼ã¨ããããã¹ããããååããã¯ã©ã¹ã®å¤å´ã§ä½¿ãã«ã¯ãã¯ã©ã¹åã«ãã修飾ãå¿
è¦ã§ããã
struct X
{
typedef int I ;
class Inner { } ;
I member ;
} ;
X::I object ;
ã¯ã©ã¹ã«ã¯ãåºæ¬ã¯ã©ã¹æå®ã«ãã£ã¦åºæ¬ã¯ã©ã¹ãæå®ãããã¨ãã§ãããåºæ¬ã¯ã©ã¹æå®ã¯ã以ä¸ã®ãããªææ³ã§ããã
åºæ¬å¥:
: åºæ¬æå®åãªã¹ã
åºæ¬æå®åãªã¹ã:
åºæ¬æå®å ...opt
åºæ¬æå®åãªã¹ã, åºæ¬æå®å ...opt
åºæ¬æå®å:
ã¢ããªãã¥ã¼ãæå®åopt åºæ¬åæå®å
ã¢ããªãã¥ã¼ãæå®åopt virtual ã¢ã¯ã»ã¹æå®åopt åºæ¬åæå®å
ã¢ããªãã¥ã¼ãæå®åopt ã¢ã¯ã»ã¹æå®å virtualopt åºæ¬åæå®å
åºæ¬åæå®å:
ã¯ã©ã¹ãããã¯decltype
ã¢ã¯ã»ã¹æå®å:
private
protected
public
åºæ¬ã¯ã©ã¹æå®åã«æå®ãããã¯ã©ã¹ã®ãã¨ããåºæ¬ã¯ã©ã¹ï¼base classï¼ã¨ãããã¾ããåºæ¬ã¯ã©ã¹ãæå®ããã¯ã©ã¹ããåºæ¬ã¯ã©ã¹ã«å¯¾ãããæ´¾çã¯ã©ã¹ï¼derived classï¼ã¨ãããã¯ã©ã¹ã®åºæ¬ã¯ã©ã¹æå®ã«æå®ããã¦ããã¯ã©ã¹ããã¯ã©ã¹ã®ç´æ¥ã®åºæ¬ã¯ã©ã¹ï¼direct base classï¼ã¨ãããåºæ¬ã¯ã©ã¹æå®ã«ã¯æå®ããã¦ããªããã®ã®ãç´æ¥ã®åºæ¬ã¯ã©ã¹ãéãã¦åºæ¬ã¯ã©ã¹ã¨ãªã£ã¦ããã¯ã©ã¹ããã¯ã©ã¹ã®éæ¥ã®åºæ¬ã¯ã©ã¹ï¼indirect base classï¼ã¨ãããåã«åºæ¬ã¯ã©ã¹ã¨ããå ´åãç´æ¥ã®åºæ¬ã¯ã©ã¹ã¨éæ¥ã®åºæ¬ã¯ã©ã¹ã®ä¸¡æ¹ãæå³ããã
ä»ã®ããã°ã©ãã³ã°è¨èªã®ä¸ã«ã¯ãåºæ¬ã¯ã©ã¹ã®ãã¨ãã¹ã¼ãã¼ã¯ã©ã¹ã¨å¼ã³ãæ´¾çã¯ã©ã¹ã®ãã¨ããµãã¯ã©ã¹ã¨åä»ãã¦ããè¨èªããããC++ã§ã¯ããã®ãããªå称ã¯ç¨ããªããããã¯ãã¹ã¼ãã¼ã¨ãµãã§ã¯æå³ãåããã«ããã¨ãä»ãªãã¬Bjarne Stroustrupèªèº«ãèããããã§ããããã®ãããC++ã§ã¯ãã¹ã¼ãã¼ã®ãããã«åºæ¬ï¼baseï¼ããµãã®ãããã«æ´¾çï¼derivedï¼ã¨ããè¨èãç¨ãããã¨ã«ãªã£ãã
åºæ¬ã¯ã©ã¹ã¯ãåºæ¬æå®åã«è¨è¿°ãããããã¯ã
struct Base { } ;
struct Derived1 : Base { } ;
struct Derived2 : Derived1 { } ;
ããã§ã¯ãDerived1ã®åºæ¬ã¯ã©ã¹ã¯Baseã§ãããDerived2ã®åºæ¬ã¯ã©ã¹ã¯Derived1ã¨Baseã§ãããDerived2ã®ç´æ¥ã®åºæ¬ã¯ã©ã¹ã¯Derived1ãéæ¥ã®åºæ¬ã¯ã©ã¹ã¯Baseã§ããã
æ´¾çï¼derivedï¼ã¨ç¶æ¿ï¼inheritedï¼ã¨ããè¨èã«ã¯ãè¦æ ¼ä¸ãæ確ãªéããããã
æ´¾çã¨ããè¨èã¯ãæ´¾çã¯ã©ã¹ã¨åºæ¬ã¯ã©ã¹ã®é¢ä¿ãè¨è¿°ããããã«ç¨ãããããããã¯ã©ã¹ãåºæ¬ã¯ã©ã¹ãæã¤å ´åããããã¯ã©ã¹ã¯ãåºæ¬ã¯ã©ã¹ãããæ´¾çãããï¼A class is derived from its base classï¼ãã¨ããããDerivedã¯ã©ã¹ã¯Baseã¯ã©ã¹ããæ´¾çããã¦ããï¼The Derived class is derived from the Base class.ï¼ãã¨ããã°ã以ä¸ã®ãããªã³ã¼ããæå³ããã
struct Base { } ;
struct Derived : Base { } ;
ãã®å ´åãDerivedã¯ã©ã¹ã¯Baseã¯ã©ã¹ããæ´¾çããã¦ãããã¨ãããã¯ã©ã¹ã®æ´¾çé¢ä¿ã«ãç¶æ¿ã¨ããè¨èã使ãã®ã¯èª¤ãã§ããã
ãã ããç¶æ¿ããã¦ããåºæ¬ã¯ã©ã¹ï¼inherited base classï¼ã¨ããè¨ãæ¹ããããã¨ã¯ãããããã¯ã対象ãåºæ¬ã¯ã©ã¹ã§ãããã«å¯¾ãã¦æ´¾çã¨ããè¨èãç¨ããã¨ãæ´¾çã¯ã©ã¹ã¨ããæå³ã«ãªã£ã¦ãã¾ãããã ã
ç¶æ¿ã¨ããè¨èã¯ãã¯ã©ã¹ã®ã¡ã³ãã¼ã«å¯¾ãã¦ç¨ããããããåºæ¬ã¯ã©ã¹ã®ã¡ã³ãã¼ã¯ãæ´¾çã¯ã©ã¹ã«ç¶æ¿ãããï¼The Base class's member is inherited by the derived class.ï¼ãã¨ãããä¾ãã°ããBaseã¯ã©ã¹ã®ã¡ã³ãã¼é¢æ°fã¯ãDerivedã¯ã©ã¹ã«ãç¶æ¿ããã¦ããï¼The Base class's member function f is inherited by the Derived classï¼ãã¨ããã°ã以ä¸ã®ãããªã³ã¼ããæå³ããã
struct Base { void f() ; } ;
// Derivedã¯Base::fãç¶æ¿
struct Derived : Base { } ;
ã¯ã©ã¹ã®ã¡ã³ãã¼ã«å¯¾ãã¦ãæ´¾çã¨ããè¨èã¯ä½¿ãã®ã¯èª¤ãã§ããã
åºæ¬ã¯ã©ã¹æå®åã«...ã使ãããå ´åãããã¯å±éã¨ã¿ãªãããã
template < typename ... Types >
struct X : Types ... { } ;
ã¢ã¯ã»ã¹æå®ã«ã¤ãã¦ã¯ãã¡ã³ãã¼ã®ã¢ã¯ã»ã¹æå®ãåç
§ã
åºæ¬ã¯ã©ã¹ã¯ãè¤æ°æå®ãããã¨ãã§ãããããããè¤æ°ã®åºæ¬ã¯ã©ã¹ã¨ãããè¤æ°ã®åºæ¬ã¯ã©ã¹ãæå®ãããã¨ããä¿ã«ãå¤éç¶æ¿ï¼Multiple Inheritanceï¼ã¨ãããã¨ãããããããã¯ãC++ã®è¦æ ¼ä¸ãæ£ããç¨èªã§ã¯ãªããç¶æ¿ã¯ãåºæ¬ã¯ã©ã¹ã®ã¡ã³ãã¼ãæ´¾çã¯ã©ã¹ãåãç¶ããã¨ãæå³ããç¨èªã§ãã£ã¦ãã¯ã©ã¹ã®æ´¾çé¢ä¿ã表ãã®ã«ä½¿ãè¨èã§ã¯ãªãããã ã
ãã ããæ´å²çã«è¨ãã°ãMultiple Inheritanceã¨ããè¨èãæåã«ä½¿ã£ãã®ã¯ãä»ãªãã¬Bjarne Stroustrupãæ¬äººã§ãããå½æãStroustrupæ°ãè¤æ°ã®åºæ¬ã¯ã©ã¹ã®è¨è¨ããã¦ããæã«ä½¿ã£ãè¨èããå¤éç¶æ¿ã§ãã£ããã¡ãªã¿ã«ãå¤éç¶æ¿ãåãã¦ä½¿ãããã³ã¼ãã¯ãJerry Schwarzã«ãã£ã¦æ¸ãããiostreamã§ããã
è¤æ°ã®åºæ¬ã¯ã©ã¹ã¯ãã³ã³ãã§åºåããã¨ã«ãã£ã¦æå®ããã
struct A { } ; struct B { } ; struct C { } ;
struct D
: A, B, C
{ } ;
ãã®ä¾ã§ã¯ãDã¯ãAãBãCã¨ãã3åã®åºæ¬ã¯ã©ã¹ãæã£ã¦ããã
åãã¯ã©ã¹ãè¤æ°ãç´æ¥ã®åºæ¬ã¯ã©ã¹ã¨ãã¦æå®ãããã¨ã¯åºæ¥ãªããéæ¥ã®åºæ¬ã¯ã©ã¹ã¨ãã¦ã¯æå®ã§ããã
struct Base { } ;
struct Derived
: Base, Base // ã¨ã©ã¼ãç´æ¥ã®åºæ¬ã¯ã©ã¹
{ } ;
struct Derived1 : Base { } ;
struct Derived2 : Base { } ;
struct Derived3
: Derived1, Derived2 // OKãéæ¥ã®åºæ¬ã¯ã©ã¹
{ } ;
ãã®å ´åãDerived3ã¯ãBaseã¯ã©ã¹ã®ãµããªãã¸ã§ã¯ããã2åæã¤ãã¨ã«ãªãã
åºæ¬ã¯ã©ã¹ã«ãvirtualãæå®ããã¦ããªãå ´åãévirtualåºæ¬ã¯ã©ã¹ï¼non-virtual base classï¼ã¨ãªããévirtualåºæ¬ã¯ã©ã¹ã«ã¯ãããããç¬ç«ãããµããªãã¸ã§ã¯ããå²ãå½ã¦ãããã
åãã¯ã©ã¹ãè¤æ°ãévirtualåºæ¬ã¯ã©ã¹ã¨ãã¦åå¨ãããã¨ã¯ãåºæ¬ã¯ã©ã¹ã®ã¡ã³ãã¼ã®ååã«å¯¾ãããªãã¸ã§ã¯ãã容æã«ææ§ã«ãªãããã®ã¨ããæ´¾çã¯ã©ã¹ããåºæ¬ã¯ã©ã¹ã®ã¡ã³ãã¼ã使ãã«ã¯ãååãæ£ãã修飾ããªããã°ãªããªãã
struct Base { int member ; } ;
struct Derived1 : Base { } ;
struct Derived2 : Base { } ;
// Derived3ã«ã¯ã2åã®Baseãµããªãã¸ã§ã¯ããåå¨ãã
struct Derived3 : Derived1, Derived2
{
void f()
{
member ; // ã¨ã©ã¼ãææ§
Base::member ; // ã¨ã©ã¼ãææ§
Derived1::member ; // OK
Derived2::member ; // OK
}
} ;
int main()
{
Derived3 x ;
x.member ; // ã¨ã©ã¼ãææ§
x.Derived1::member ; // OK
x.Derived2::member ; // OK
}
ãã ããstaticã¡ã³ãã¼ã®ååã¯ãææ§ã«ãªããªããããã¯ãstaticã¡ã³ãã¼ã®å©ç¨ã«ã¯ãã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã¯å¿
è¦ãªãããã§ããã
struct Base
{
static void static_member() { }
static int static_data_member ;
} ;
int Base::static_data_member = 0 ;
struct Derived1 : Base { } ;
struct Derived2 : Base { } ;
struct Derived3 : Derived1, Derived2
{
void f()
{
static_member() ; // OK
static_data_member ; // OK
}
} ;
ç´æ¥ãéæ¥ã®ä¸¡æ¹ã®åºæ¬ã¯ã©ã¹ã«ãåãã¯ã©ã¹ãæã¤ãã¨ã¯å¯è½ã§ããããã ãããã®ãããªæ´¾çã¯ã©ã¹ã¯ãåºæ¬ã¯ã©ã¹ã®éstaticã¡ã³ãã¼ã使ããã¨ãã§ããªãããªããªããåºæ¬ã¯ã©ã¹ã®ååèªä½ã®ææ§æ§ã解決ããæ¹æ³ããªãããã ã
struct Base
{
int member() ; // éstaticã¡ã³ãã¼
static void static_member() { } // staticã¡ã³ãã¼
} ;
struct Derived1 : Base { } ;
// Baseã¨ããååèªä½ãææ§ã«ãªã
struct Derived2 : Base, Derived1
{
void f()
{
// Baseã®éstaticã¡ã³ãã¼ã使ãæ¹æ³ã¯ãªã
static_member() ; // OKãstaticã¡ã³ãã¼ã¯ä½¿ãã
}
} ;
ãã®ãããç´æ¥ãéæ¥ã®ä¸¡æ¹ã§åãã¯ã©ã¹ãåºæ¬ã¯ã©ã¹ã«æã¤æ´¾çã¯ã©ã¹ã®å©ç¨ã¯ãããªãå¶éãããã
åºæ¬ã¯ã©ã¹ã«ãvirtualãæå®ããã¦ããå ´åãvirtualåºæ¬ã¯ã©ã¹ï¼virtual base classï¼ã¨ãããvirtualåºæ¬ã¯ã©ã¹ã«ã¯ãã²ã¨ã¤ãããªãã¸ã§ã¯ããå²ãå½ã¦ãããªããvirtualåºæ¬ã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã¯ãæ´¾çã¯ã©ã¹ã§å
±æãããã
struct L { } ;
struct A : virtual L { } ;
struct B : virtual L { } ;
struct C : A, B { } ;
ãã®ä¾ã§ãCã¯ã©ã¹ã«ã¯ãLã®ãµããªãã¸ã§ã¯ãã¯1ååå¨ãããããã¯ãAãBã§å
±æãããã
virtualåºæ¬ã¯ã©ã¹ã§ã¯ããµããªãã¸ã§ã¯ããå
±æããã¦ãããããvirtualåºæ¬ã¯ã©ã¹ã®ã¡ã³ãã¼ã¯ãææ§ã«ãªããªãã
struct Base { int member ; } ;
struct Derived1 : virtual Base { } ;
struct Derived2 : virtual Base { } ;
struct Derived3 : Derived1, Derived2
{
void f()
{
member ; // OK
}
} ;
évirtualåºæ¬ã¯ã©ã¹ã¨virtualåºæ¬ã¯ã©ã¹ã¯ã両æ¹æã¤ãã¨ãã§ããã
struct B { } ;
struct X : virtual B { } ;
struct Y : virtual B { } ;
struct Z : B { } ;
struct A : X, Y, Z { } ;
ãã®ä¾ã§ã¯ãAã¯ã©ã¹ã«ã¯ãBã®ãµããªãã¸ã§ã¯ãã¯ã2ååå¨ãããXãYã§å
±æããããµããªãã¸ã§ã¯ãã¨ãZã®ãµããªãã¸ã§ã¯ãã§ããã
ã¡ã³ãã¼ã®ååæ¢ç´¢ã¯ããããé£ãããæ´¾çã¯ã©ã¹ã®ã¡ã³ãã¼åã¯ãåºæ¬ã¯ã©ã¹ã®ã¡ã³ãã¼åãé ãã¨ãããã¨ã ãããã¡ã³ãã¼åãååæ¢ç´¢ããéã«ãæ´¾çã¯ã©ã¹ã§ååãè¦ã¤ãã£ãå ´åããã®æç¹ã§ååæ¢ç´¢ã¯çµäºãããåºæ¬ã¯ã©ã¹ã®ã¡ã³ãã¼ãæ¢ããã¨ã¯ãªãã
struct Base
{
void f( int ) { }
} ;
struct Derived : Base
{
void f( double ) { }
} ;
int main()
{
Derived object;
object.f( 0 ) ; // Derived::f( double )ãå¼ã°ãã
}
ããã§ãDerivedã¯ã©ã¹ã«ã¯ãäºã¤ã®fã¨ããååã®ã¡ã³ãã¼ãåå¨ãããDerived::fã¨Base::fã§ããããããååæ¢ç´¢ã«ãã£ã¦ä¸¡æ¹ã®ååãçºè¦ãããå ´åããªã¼ãã¼ãã¼ã解決ã«ãã£ã¦ãBase::f(int)ãé¸ã°ããã¯ãã§ãããããããå®éã«ã¯ãDerived::f(double)ãé¸ã°ãããããã¯ãDerivedã¯ã©ã¹ã«ãfã¨ããååã®ã¡ã³ãã¼ãåå¨ããã®ã§ããã®æç¹ã§ååæ¢ç´¢ãçµäºããããã§ãããBaseã®ã¡ã³ãã¼åã¯çºè¦ãããªããååãçºè¦ãããªã以ä¸ããªã¼ãã¼ãã¼ã解決ã«ãã£ã¦é¸ã°ãããã¨ããªãã
ããã¯ãååæ¢ç´¢ã«å¯¾ããã«ã¼ã«ãªã®ã§ãåã¯é¢ä¿ããªãã
// fã¨ããååã®intåã®ãã¼ã¿ã¡ã³ãã¼
struct Base { int f ; } ;
// fã¨ããååã®void (void)åã®ã¡ã³ãã¼é¢æ°
struct Derived : Base { void f( ) { } } ;
int main()
{
Derived object;
object.f = 0 ; // ã¨ã©ã¼ãã¡ã³ãã¼é¢æ°Derived::fã«0ã代å
¥ãããã¨ã¯ã§ããªã
object.Base::f = 0 ; // OKãæ示çãªä¿®é£¾
}
ãããã£ã¦ãåºæ¬ã¯ã©ã¹ã¨åãååã®ã¡ã³ãã¼ãæ´¾çã¯ã©ã¹ã§ä½¿ãéã«ã¯ã注æãå¿
è¦ã§ããã
ååæ¢ç´¢ã¨ããä»çµã¿ãèããã«ããã®æåãèããå ´åãããã¯ãæ´¾çã¯ã©ã¹ã®ã¡ã³ãã¼åããåºæ¬ã¯ã©ã¹ã®ã¡ã³ãã¼åããé ãã¦ããã¨èãããã¨ãã§ããããããåºæ¬ã¯ã©ã¹ã®ã¡ã³ãã¼åãé ããããªãå ´åãusing宣è¨ã使ããã¨ãã§ãããusing宣è¨ã使ãã¨ãåºæ¬ã¯ã©ã¹ã®ã¡ã³ãã¼åããæ´¾çã¯ã©ã¹ã®ã¹ã³ã¼ãã«å°å
¥ãããã¨ãã§ããã
struct Base
{
void f( int ) { }
} ;
struct Derived : Base
{
using Base::f ; // using宣è¨
void f( double ) { }
} ;
int main()
{
Derived object;
object.f( 0 ) ; // Base::f( int )ãå¼ã°ãã
}
ååæ¢ç´¢ã§ãæ´¾çã¯ã©ã¹ã®ã¡ã³ãã¼ãè¦ã¤ãããªãå ´åã¯ãç´æ¥ã®åºæ¬ã¯ã©ã¹ã®ã¡ã³ãã¼ãããååãæ¢ãããã
struct Base { int member ; } ;
struct Derived : Base
{
void f()
{
member ; // Base::member
}
} ;
ã¡ã³ãã¼åãæ¢ãåºæ¬ã¯ã©ã¹ã¯ãç´æ¥ã®åºæ¬ã¯ã©ã¹ã ãã§ãããéæ¥ã®åºæ¬ã¯ã©ã¹ã®ã¡ã³ãã¼ã¯ãç´æ¥ã®åºæ¬ã¯ã©ã¹ãéãã¦ãæ¢ãããã
struct A { int member ; } ;
struct B : A { } ;
struct C : B
{
void f()
{
member ; // A::member
}
} ;
ãã®ä¾ã§ã¯ãC::fã§memberã¨ããååã®ã¡ã³ãã¼ã使ã£ã¦ãããCã¯ã©ã¹ã«ã¯memberã¨ããååã®ã¡ã³ãã¼ãè¦ã¤ãããªãã®ã§ãååæ¢ç´¢ã¯Bã¯ã©ã¹ã«ç§»ããã¯ã©ã¹ã¯ãåºæ¬ã¯ã©ã¹ã®ã¡ã³ãã¼åãç¶æ¿ãã¦ããããã®ãããBã¯ã©ã¹ã®åºæ¬ã¯ã©ã¹ã®Aã¯ã©ã¹ã®ã¡ã³ãã¼åã¯ãBã¯ã©ã¹ã®ã¹ã³ã¼ããããçºè¦ãããã¨ãã§ããã
ç´æ¥ã®åºæ¬ã¯ã©ã¹ãè¤æ°ããå ´åãããããã®ç´æ¥ã®åºæ¬ã¯ã©ã¹ãããååãæ¢ãããããã®éãè¤æ°ã®ã¯ã©ã¹ããåãååãçºè¦ãããååã®æå³ãéãå ´åãååæ¢ç´¢ã¯ç¡å¹ã¨ãªãã
struct Base1 { void member( int ) { } } ;
struct Base2 { void member( double ) { } } ;
struct Derived : Base1, Base2 // è¤æ°ã®ç´æ¥ã®åºæ¬ã¯ã©ã¹
{
void f()
{
member( 0 ) ; // ã¨ã©ã¼ãååæ¢ç´¢ãç¡å¹
Base1::member( 0 ) ; // OK
}
} ;
ããã¯ãmemberã¨ããååã«å¯¾ããè¤æ°ã®ç´æ¥ã®åºæ¬ã¯ã©ã¹ã§ãè¤æ°ã®åãååãè¦ã¤ããããããæå³ãéã£ã¦ããã®ã§ãååæ¤ç´¢ãç¡å¹ã¨ãªãããã®çµæãmemberã¨ããååãè¦ã¤ããããã¨ã©ã¼ã¨ãªãã
ããããã®ä¾ã§ãDerivedãããæ示çãªä¿®é£¾ãããã«ã両æ¹ã®åºæ¬ã¯ã©ã¹ã®ã¡ã³ãã¼é¢æ°ãå¼ã³åºãããå ´åãusing宣è¨ã使ããã
struct Base1 { void member( int ) { } } ;
struct Base2 { void member( double ) { } } ;
struct Derived : Base1, Base2
{
// åºæ¬ã¯ã©ã¹ã®ã¡ã³ãã¼åãDerivedã¹ã³ã¼ãã§å®£è¨ãã
using Base1::member ;
using Base2::member ;
void f()
{
member( 0 ) ; // OKããªã¼ãã¼ãã¼ã解決ã«ãããBase1::member(int)ãå¼ã°ãã
}
} ;
ãã®ä¾ã¯ãè¤æ°ã®ç´æ¥ã®åºæ¬ã¯ã©ã¹ãããå ´åã®å¶éã§ãããè¤æ°ã®éæ¥ã®åºæ¬ã¯ã©ã¹ã§ã¯ãååæ¢ç´¢ã失æãããã¨ã¯ãªãããã ããååæ¢ç´¢ã®çµæã¨ãã¦ãè¤æ°ã®ååãçºè¦ãããææ§ã«ãªããã¨ã¯ããã
æ¬æ¸ã®ãµã³ãã«ã³ã¼ãã¯ã解説ããææ³ã®ããã®æå°éã®ã³ã¼ãã§ãããvirtualé¢æ°ãæã¤ã¯ã©ã¹ãvirtualãã¹ãã©ã¯ã¿ã¼ãæããªããã¨ããããããã¯ç¾å®ã§ã¯ã»ã¨ãã©ã®å ´åãä¸é©åã§ããã
ã¡ã³ãã¼é¢æ°ã«virtualæå®åãæå®ããã¨ãvirtualé¢æ°ã¨ãªããvirtualé¢æ°ã宣è¨ãã¦ããã¯ã©ã¹ããããã¯virtualé¢æ°ãç¶æ¿ãã¦ããã¯ã©ã¹ã¯ãããªã¢ã¼ãã£ãã¯ã¯ã©ã¹ï¼polymorphic classï¼ã¨ãªãã
struct Base
{
virtual void f() { } // virtualé¢æ°
} ;
struct Derived : Base { } ;
Baseã¨Derivedã¯ãããªã¢ã¼ãã£ãã¯ã¯ã©ã¹ã§ããã
ã¯ã©ã¹ãããªã¢ã¼ãã£ãã¯ã§ãããã©ããã¨ãããã¨ã¯ãdynamic_castãtypeidã使ãéã«ãéè¦ã§ããã
åºæ¬ã¯ã©ã¹ã®virtualé¢æ°ã¯ãæ´¾çã¯ã©ã¹ã®ã¡ã³ãã¼ã«ãåãååãåãä»®å¼æ°ãªã¹ããåãCV修飾åãåããªãã¡ã¬ã³ã¹ä¿®é£¾åã¨ããæ¡ä»¶ãæºããã¡ã³ãã¼é¢æ°ããã£ãå ´åããªã¼ãã¼ã©ã¤ããããããã®æãæ´¾çã¯ã©ã¹ã®ã¡ã³ãã¼é¢æ°ã¯ãvirtualæå®åããªãã¦ããèªåçã«virtualé¢æ°ã«ãªãã
struct A { virtual void f() {} } ;
struct B : A { } ; // ãªã¼ãã¼ã©ã¤ãããªã
struct C : A
{
void f() { } // ãªã¼ãã¼ã©ã¤ã
} ;
struct D : C
{
void f(int) { } // ãªã¼ãã¼ã©ã¤ãããªã
void f() const { } // ãªã¼ãã¼ã©ã¤ãããªã
} ;
// ãªãã¡ã¬ã³ã¹ä¿®é£¾åãéãä¾
struct Base { virtual void f() & { } } ;
struct Derived : Base { void f() && { } } ;
ãã¡ãããvirtualãã¤ãã¦ãããã
struct Base { virtual f() { } } ;
struct Derived : Base { virtual f() { } } ; // ãªã¼ãã¼ã©ã¤ã
æ´¾çã¯ã©ã¹ã§ãæå¾ã«ãªã¼ãã¼ã©ã¤ãããvirtualé¢æ°ãããã¡ã¤ãã«ãªã¼ãã¼ã©ã¤ãã¼ï¼final overriderï¼ã¨å¼ã¶ãããã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã«å¯¾ãã¦ãvirtualé¢æ°ãå¼ã³åºãéã¯ããªãã¸ã§ã¯ãã®å®è¡æã®åã«ãã£ã¦ãæå¾ã«ãªã¼ãã¼ã©ã¤ãããvirtualé¢æ°ãå¼ã³åºããããããã¯ãåºæ¬ã¯ã©ã¹ã®ãã¤ã³ã¿ã¼ããªãã¡ã¬ã³ã¹ãçµç±ãã¦ãªãã¸ã§ã¯ãã使ã£ãå ´åã§ããåæ§ã§ãããé常ã®ã¡ã³ãã¼é¢æ°ã¯ãvirtualé¢æ°ã¨ã¯éããå®è¡æã®åãã§ãã¯ãè¡ããªãããªãã¸ã§ã¯ããæãã¦ãããªãã¡ã¬ã³ã¹ããã¤ã³ã¿ã¼ã®åã«ãã£ã¦ã決å®ãããã
// virtualé¢æ°ã¨évirtualé¢æ°ã®éãã®ä¾
struct A
{
virtual void virtual_function() { }
void function() { }
} ;
struct B : A
{
virtual void virtual_function() { }
void function() { }
} ;
struct C : B
{
virtual void virtual_function() { }
void function() { }
} ;
void call( A & ref )
{
ref.virtual_function() ;
ref.function() ;
}
int main()
{
A a ; B b ; C c ;
call( a ) ; // A::virtual_function, A::functionãå¼ã³åºããã
call( b ) ; // B::virtual_function, A::functionãå¼ã³åºããã
call( c ) ; // C::virtual_function, A::functionãå¼ã³åºããã
}
Aã¯ãvirtual_functionã¨functionã¨ããååã®virtualé¢æ°ãæã£ã¦ãããAããæ´¾çãã¦ããBãBããæ´¾çãã¦ããCã¯ããªã¼ãã¼ã©ã¤ããã¦ãããcallé¢æ°ã®ä»®å¼æ°refã¯ããªãã¸ã§ã¯ãã®åããå®éã«ä½ã§ãããã¯ãå®è¡æã«ããåãããªããvirtualé¢æ°ã§ããvirtual_functionã¯ããªãã¸ã§ã¯ãã®åã«åããã¦æ£ããå¼ã³åºãããããvirtualé¢æ°ã§ã¯ãªãfunctionã¯ãAã®ã¡ã³ãã¼ãå¼ã³åºãããã
virtæå®å(virt-specifier)ã¯ãfinalãoverrideã§ãvirtualé¢æ°ã®å®£è¨åã®å¾ãpureæå®åã®åã«è¨è¿°ã§ããã
// virtæå®åã®ææ³ã®ä¾ç¤ºã®ããã®è¨è¿°
virtual f() final override = 0 ;
finalãæå®ãããvirtualé¢æ°ãæã¤ã¯ã©ã¹ããæ´¾çããã¯ã©ã¹ããåvirtualé¢æ°ããªã¼ãã¼ã©ã¤ãããå ´åã¯ã¨ã©ã¼ã«ãªãã
struct base
{
virtual void f() { }
} ;
struct derived
{
virtual void f() final { }
} ;
struct ok : derived
{
// OK
} ;
struct error : derived
{
// ã¨ã©ã¼ãfinalæå®ããã¦ããderived::fããªã¼ãã¼ã©ã¤ã
virtual void f() { }
} ;
virtualé¢æ°ã«finalãæå®ããã¨ããã以ä¸ã®ãªã¼ãã¼ã©ã¤ããç¦æ¢ã§ããã
overrideãæå®ãããvirtualé¢æ°ããåºæ¬ã¯ã©ã¹ã®ã¡ã³ãã¼é¢æ°ããªã¼ãã¼ã©ã¤ããã¦ããªãå ´åãã¨ã©ã¼ã¨ãªãã
struct base
{
virtual void virtual_function() { }
} ;
struct ok : base
{
// OKãok::virtual_functionã¯base::virtual_functionããªã¼ãã¼ã©ã¤ããã¦ãã
virtual void virtual_function() override { }
} ;
struct typo : base
{
// OKãtypo::virtal_functionã¯base::virtual_functionã¨ã¯å¥ã®virtualé¢æ°
virtual void virtal_function() { }
} ;
struct error : base
{
// ã¨ã©ã¼ãerror::virtal_functionã¯ãªã¼ãã¼ã©ã¤ããã¦ããªã
virtual void virtal_function() override { }
} ;
ããã«ãããã¿ã¤ããã¹ã«ããäºç´°ãªééããã³ã³ãã¤ã«æã«æ¤åºã§ããã
ãªã¼ãã¼ã©ã¤ãã§ãããã¨ã«æ³¨æã以ä¸ã®ã³ã¼ãã¯ã¨ã©ã¼ã§ããã
struct base
{
void f() { } // évirtualé¢æ°
} ;
struct error : base
{
// ã¨ã©ã¼ããªã¼ãã¼ã©ã¤ããã¦ããªã
virtual void f() override { }
} ;
finalã¨overrideã両æ¹æå®ãããã¨ãã§ããã
virtualé¢æ°ããªã¼ãã¼ã©ã¤ãããé¢æ°ã¯ãæ»ãå¤ã®åãåãã§ãªãã¦ãæ§ããªãããã ããä½ã§ãããã¨ããããã§ã¯ãªããæ»ãå¤ã®åã¯ãã¾ã£ããåãåããç¸äºå¤æå¯è½ï¼covariantï¼ã§ãªããã°ãªããªããcovariantã¯ã以ä¸ã®ãããªæ¡ä»¶ããäºãã«æºãããåã®ãã¨ã§ããã
ä»ãé¢æ°D::fããé¢æ°B::fããªã¼ãã¼ã©ã¤ããã¦ããã¨ããã
// D::fãB::fã®ä¾
struct B { virtual æ»ãå¤ã®å f() ; } ;
struct D : B { virtual æ»ãå¤ã®å f() ; } ;
ãã®å ´åãæ»ãå¤ã®åã¯ã以ä¸ã®æ¡ä»¶ãæºãããªããã°ãªããªãã
ãäºãã«ã¯ã©ã¹ã¸ã®ãã¤ã³ã¿ã¼ããããã¯ããäºãã«ã¯ã©ã¹ã¸ã®lvalueãªãã¡ã¬ã³ã¹ããããã¯ããäºãã«ã¯ã©ã¹ã¸ã®rvalueãªãã¡ã¬ã³ã¹ã§ãããã¨ã
çæ¹ããã¤ã³ã¿ã¼ã§çæ¹ããªãã¡ã¬ã³ã¹ã®å ´åããçæ¹ãlvalueãªãã¡ã¬ã³ã¹ã§çæ¹ãrvalueãªãã¡ã¬ã³ã¹ã®å ´åã¯ãä¸é©ã§ããããã¡ããããã¤ã³ã¿ã¼ã§ããªãã¡ã¬ã³ã¹ã§ããªãåã¯ä¸é©ã§ãããã¾ããã¯ã©ã¹ã§ããªãåã¸ã®ãã¤ã³ã¿ã¼ããªãã¡ã¬ã³ã¹ãä¸é©ã§ããã
// ãã¤ã³ã¿ã¼
struct B { virtual B * f() ; } ;
struct D : B { virtual D * f() ; } ;
// lvalueãªãã¡ã¬ã³ã¹
struct B { virtual B & f() ; } ;
struct D : B { virtual D & f() ; } ;
// rvalueãªãã¡ã¬ã³ã¹
struct B { virtual B && f() ; } ;
struct D : B { virtual D && f() ; } ;
B::fã®æ»ãå¤ã®åã®ã¯ã©ã¹ã¯ãD::fã®æ»ãå¤ã®åã®ã¯ã©ã¹ã¨åãããææ§ããªãã¢ã¯ã»ã¹ã§ããåºæ¬ã¯ã©ã¹ã§ãªããã°ãªããªãã
ãªã¼ãã¼ã©ã¤ããã¦ããé¢æ°ããåºæ¬ã¯ã©ã¹ãæ»ãå¤ã«ä½¿ã£ã¦ããããããããã¯ã©ã¹ã®æ´¾çé¢ä¿ã«ãªãå ´åã¯ãä¸é©ã§ãããprivateæ´¾çãã¦ãã¦ãæ´¾çã¯ã©ã¹ããã¯ã¢ã¯ã»ã¹ã§ããªãå ´åããåºæ¬ã¯ã©ã¹ã®ãµããªãã¸ã§ã¯ããè¤æ°ãã£ã¦ææ§ãªå ´åã¯ã¨ã©ã¼ã¨ãªãã
struct Base { } ; // åºæ¬ã¯ã©ã¹
struct Derived : Base { } ; // æ´¾çã¯ã©ã¹
struct Other { } ; // BaseãDerivedã¨ã¯æ´¾çé¢ä¿ã«ãªãã¯ã©ã¹
// ã¯ã©ã¹ãåã
struct B { virtual Base & f() ; } ;
struct D : B { virtual Base & f() ; } ;
// B::fã®ã¯ã©ã¹ã¯D::fã®ã¯ã©ã¹ã®åºæ¬ã¯ã©ã¹
struct B { virtual Base & f() ; } ;
struct D : B { virtual Derived & f() ; } ;
// ã¨ã©ã¼
struct B { virtual Derived & f() ; } ;
struct D : B { virtual Base & f() ; } ;
// ã¨ã©ã¼
struct B { virtual Base & f() ; } ;
struct D : B { virtual Other & f() ; } ;
両æ¹ã®ãã¤ã³ã¿ã¼ã¯åãCV修飾åãæããªããã°ãªããªããD::fã®æ»ãå¤ã®åã®ã¯ã©ã¹ã¯ãB::fã®æ»ãå¤ã®åã®ã¯ã©ã¹ã¨åãCV修飾åãæã¤ãããããã¯å°ãªãCV修飾åãæããªããã°ãªããªãã
è£è¶³ï¼ãã¤ã³ã¿ã¼ã«å¯¾ããCV修飾åã¨ã¯ãT cv1 * cv2ã¨ããåãããå ´åãcv2ã§ãããã¯ã©ã¹ã«å¯¾ããCV修飾åã¯ãcv1ã§ããã
// int *ã«å¯¾ããCV修飾å
int * const
// intã«å¯¾ããCV修飾å
const int *
int const *
// 両æ¹ã®ãã¤ã³ã¿ã¼ã¯åãCV修飾åãæããªããã°ãªããªãä¾
// ãã¤ã³ã¿ã¼ã®CV修飾åã¯const
struct B { virtual B * const f() ; } ;
// OK
struct D : B { virtual D * const f() ; } ;
// ã¨ã©ã¼ã®Dã¯ã©ã¹ã®ä¾ããã¤ã³ã¿ã¼ã®CV修飾åãä¸è´ãã¦ããªã
struct D : B { virtual D * f() ; } ;
struct D : B { virtual D * volatile const f() ; } ;
struct D : B { virtual D * const volatile f() ; } ;
// D::fã®æ»ãå¤ã®åã®ã¯ã©ã¹ã¯ãB::fã®æ»ãå¤ã®åã®ã¯ã©ã¹ã¨åãCV修飾åãæã¤ãã
// ãããã¯å°ãªãCV修飾åãæããªããã°ãªããªãä¾
// B::fã®æ»ãå¤ã®åã®ã¯ã©ã¹ã®CV修飾åã¯const
struct B { virtual B const & f() ; } ;
// åé¡ãªãDã¯ã©ã¹ã®ä¾ãCV修飾åãåããå°ãªã
struct D : B { virtual D const & f() ; } ;
struct D : B { virtual D & f() ; } ;
// ã¨ã©ã¼ã®Dã¯ã©ã¹ã®ä¾ãCV修飾åãå¤ã
struct D : B { virtual D volatile & f() ; } ;
struct D : B { virtual D const volatile & f() ; } ;
æ示çãªä¿®é£¾ãç¨ããå ´åã¯ãvirtualé¢æ°å¼ã³åºããé»å®³ããããããã¯ããªã¼ãã¼ã©ã¤ãããvirtualé¢æ°ããããªã¼ãã¼ã©ã¤ããããvirtualé¢æ°ãå¼ã³åºãã®ã«ä½¿ããã
struct Base { virtual void f() { } } ;
struct Derived : Base
{
virtual void f()
{
f() ; // Derived::fã®å¼ã³åºã
Base::f() ; // æ示çãªBase::fã®å¼ã³åºã
}
} ;
virtualé¢æ°ã¨deleteå®ç¾©ã¯ä½µç¨ã§ããããã ããdeleteå®ç¾©ã®virtualé¢æ°ããédeleteå®ç¾©ã®virtualé¢æ°ã§ãªã¼ãã¼ã©ã¤ããããã¨ã¯ã§ããªããédeleteå®ç¾©ã®virtualé¢æ°ããdeleteå®ç¾©ã®virtualé¢æ°ã§ãªã¼ãã¼ã©ã¤ããããã¨ã¯ã§ããªãã
// OKãdeleteå®ç¾©ã®virtualé¢æ°ããdeleteå®ç¾©ã®virtualé¢æ°ã§ãªã¼ãã¼ã©ã¤ããã¦ãã
struct Base { virtual void f() = delete ; } ;
struct Derived : Base { virtual void f() = delete ; } ;
// ã¨ã©ã¼ãédeleteå®ç¾©ã§ã¯ãªãvirtualé¢æ°ããdeleteå®ç¾©ã®virtualé¢æ°ã§ãªã¼ãã¼ã©ã¤ããã¦ãã
struct Base { virtual void f() { } } ;
struct Derived : Base { virtual void f() = delete ; } ;
// ã¨ã©ã¼ãdeleteå®ç¾©ã®virtualé¢æ°ããédeleteå®ç¾©ã®virtualé¢æ°ã§ãªã¼ãã¼ã©ã¤ããã¦ãã
struct Base { virtual void f() = delete ; } ;
struct Derived : Base { virtual void f() { } } ;
ãã¥ã¢æå®å:
= 0
ã¢ãã¹ãã©ã¯ãã¯ã©ã¹ï¼abstract classï¼ã¯ãæ½è±¡çãªæ¦å¿µã¨ãã¦ã®ã¯ã©ã¹ãå®ç¾ããæ©è½ã§ãããããã¯ãä¾ãã°å³å½¢ã表ãã¯ã©ã¹ã§ãããCircleãSquareãªã©ã¨ãã£ãã¯ã©ã¹ã®åºæ¬ã¯ã©ã¹ã§ããShapeããåç©ã表ãDogãCatãªã©ã¨ãã£ãã¯ã©ã¹ã®åºæ¬ã¯ã©ã¹ã§ããAnimalãªã©ãç°ãªãã¯ã©ã¹ã«å¯¾ããå
±éã®ã¤ã³ã¿ã¼ãã§ã¼ã¹ãæä¾ããç®çã«ä½¿ããã
struct Shape
{
// å³å½¢æç»ç¨ã®é¢æ°
// Shapeã¯ã©ã¹ã¯æ½è±¡çãªæ¦å¿µã§ãããå
·ä½çãªæç»æ¹æ³ãæããªã
// åã«å
±éã®ã¤ã³ã¿ã¼ãã§ã¼ã¹ã¨ãã¦æä¾ããã
virtual void draw() = 0 ;
} ;
struct Circle : Shape
{
virtual void draw() { /* åãæç» */ }
} ;
struct Square : Shape
{
virtual void draw() { /* æ£æ¹å½¢ãæç» */ }
} ;
void f( Shape * ptr )
{
ptr->draw() ; // å®è¡æã®åã«å¿ãã¦å³å½¢ãæç»ãã
}
ããã§ã¯ãShapeã¯ã©ã¹ã¨ããã®ã¯ãå
·ä½çã«æç»ããæ¹æ³ãæããªãããããããShapeã¯ã©ã¹èªä½ã®ãªãã¸ã§ã¯ãã使ããã¨ã¯æ³å®ããã¦ããªãããã®ããã«ããã®ã¯ã©ã¹èªä½ã¯æ½è±¡çãªæ¦å¿µã§ãããå®ä½ãæããªãå ´åããã¥ã¢virtualé¢æ°ã使ããã¨ã§ãå
±éã®ã¤ã³ã¿ã¼ãã§ã¼ã¹ã¨ãããã¨ãã§ããã
ä»ã®è¨èªã§ã¯ããã®æ©è½ãæ確ã«ã¯ã©ã¹ããåé¢ãã¦ããã¤ã³ã¿ã¼ãã§ã¼ã¹ãã¨ããååã®æ©è½ã«ãã¦ãããã®ããããC++ã§ã¯ãæ½è±¡ã¯ã©ã¹ããå¶éã¯ãããã®ã®ãã¯ã©ã¹ã®ä¸ç¨®ã§ããã
å°ãªãã¨ãã²ã¨ã¤ã®ãã¥ã¢virtualé¢æ°ãæã¤ã¯ã©ã¹ã¯ãã¢ãã¹ãã©ã¯ãã¯ã©ã¹ã¨ãªãããã¥ã¢virtualé¢æ°ã¯ãvirtualé¢æ°ã®å®£è¨ã«ããã¥ã¢æå®åãæ¸ããã¨ã§å®£è¨ã§ããã
ãã¥ã¢æå®å:
= 0
struct abstract_class
{
virtual void f() = 0 ;
} ;
ãã¥ã¢virtualé¢æ°ã¯ãå¼ã°ããªãéããå®ç¾©ããå¿
è¦ã¯ãªãã
struct Base
{
virtual void f() = 0 ;
virtual void g() = 0 ;
} ;
struct Derived
{
virtual void g() { }
} ;
void call_g( Base & base )
{
base.g() ;
}
int main()
{
Derived d ;
call_g( d ) ;
}
ä¸ã¤ã®é¢æ°å®£è¨ã«ãã¥ã¢æå®åã¨å®ç¾©ã両æ¹æ¸ããã¨ã¯ã§ããªãã
struct X
{
// ã¨ã©ã¼
virtual void f() = 0 { } ;
} ;
ãã ããè¤æ°ã®é¢æ°å®£è¨ã使ãã°ãã²ã¨ã¤ã®é¢æ°ã«ãã¥ã¢æå®åã¨å®ç¾©ã両æ¹ä¸ãããã¨ãã§ããã
struct X
{
// OKããã¥ã¢æå®åãä¸ããé¢æ°å®£è¨
virtual void f() = 0 ;
} ;
// OKãå®ç¾©ãä¸ããé¢æ°å®£è¨
void X::f() { }
ãã®ä»æ§ã¯ããªãã¸ã§ã¯ãã®ç ´æ£ã®éã«ä½ããã®å¦çãè¡ãããæ½è±¡ã¯ã©ã¹ã«ä½¿ããã¨ãã§ããããã¹ãã©ã¯ã¿ã¼ãç´ç²ä»®æ³é¢æ°ãã¤å®ç¾©ä»ãã®é¢æ°ã¨ãããã¨ãã§ããã
class Base
{
int * ptr ;
public :
Base( int value )
: ptr( new int(value) )
{ }
virtual ~Base() = 0 ;
} ;
Base::~Base()
{
delete ptr ;
}
ãã ãããã¹ãã©ã¯ã¿ã¼ã®å¼ã³åºãã¯ãé常ã®ã¡ã³ãã¼é¢æ°ã¨ã¯ç°ãªã£ã¦ããã®ã§ã注æãå¿
è¦ã§ããã以ä¸ã®ã³ã¼ããèããã
struct Base
{
virtual void f() = 0 ;
virtual ~Base() = 0 ;
} ;
void Base::f() { }
Base::~Base
{
// Derivedã¯ãã§ã«ç ´æ£ããã¦ããã
f() ; // ã¨ã©ã¼ãBase::fã®virtualé¢æ°å¼ã³åºãã®æåã¯æªå®ç¾©
}
struct Derived : Base
{
virtual void f() { }
virtual ~Base() { }
} ;
int main()
{
Derived d ;
}
Baseã®ãã¹ãã©ã¯ã¿ã¼å¼ã³åºãã¯åé¡ããªãããªããªãã°ãåºæ¬ã¯ã©ã¹ã®ãã¹ãã©ã¯ã¿ã¼ã¯ãããããæ示çã«ç´æ¥å¼ã³åºããããã®ããã«æ¯ãèãããã ãvirtualé¢æ°å¼ã³åºãã§ã¯ãªãã
ãã ãããã¹ãã©ã¯ã¿ã¼ã®ä¸ã§æªä¿®é£¾åã®fãå¼ã³åºãã¨ãããã¯virtualé¢æ°å¼ã³åºãã«ãªãããªãã¸ã§ã¯ãã®æ§ç¯ä¸ãç ´æ£ä¸ã«virtualé¢æ°ãå¼ã³åºããå ´åããªãã¸ã§ã¯ãã®åããããããæçµçãªæ´¾çã¯ã©ã¹ã®åã¨ã¿ãªãããããã®ãããããã§ã¯Base::fãvirtualé¢æ°å¼ã³åºããããã
Base::fã¯ãå®ç¾©ãä¸ãããã¦ã¯ãããã®ã®ãä¾ç¶ã¨ãã¦ãã¥ã¢virtualé¢æ°ã§ãããã¨ã«å¤ããã¯ãªãããã¥ã¢virtualé¢æ°ãvirtualé¢æ°å¼ã³åºãããå ´åã®æåã¯æªå®ç¾©ã§ããããã®ãããä¸è¨ã®ã³ã¼ãã¯ã以ä¸ã®ããã«ãæ示çãªä¿®é£¾åã§å¼ã³åºããé常ã®é¢æ°å¼ã³åºãã«ããªããã°ãè¦æ ¼ä¸ãåä½ãä¿è¨¼ãããªãã
Base::~Base
{
Base::f() ; // OKã修飾åã¯é常ã®é¢æ°å¼ã³åºã
}
ãã®ã=0ã¨ããææ³ã¯ãåæååã代å
¥å¼ã¨ã¯ãä½ã®é¢ä¿ããªãããã ãC++ã®ææ³ä¸ãã¡ã³ãã¼é¢æ°ã®å®£è¨ã®ä¸ã®ã=0ã¨ãããã¼ã¯ã³åããç¹å¥ãªæå³ãæã¤ãã®ã¨ãã¦æ±ã£ã¦ããã ãã§ããããã¥ã¢æå®åãè¨è¿°ããä½ç½®ã¯ãvirt-specifierã®å¾ã§ããã
struct Base { virtual void f() { } }
struct abstract_class : Base
{
virtual void f() override = 0 ; // virt-specifierã®å¾
} ;
ã¢ãã¹ãã©ã¯ãã¯ã©ã¹ã¯ãä»ã®ã¯ã©ã¹ã®åºæ¬ã¯ã©ã¹ã¨ãã¦ä½¿ããã¨ããã§ããªããã¢ãã¹ãã©ã¯ãã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã¯ãæ´¾çã¯ã©ã¹ã®ãµããªãã¸ã§ã¯ãã¨ãã¦ã®ã¿ãåå¨ãããã¨ãã§ããã
struct abstract_class
{
virtual void f() = 0 ;
} ;
struct Derived : abstract_class
{
void f() { }
} ;
ã¢ãã¹ãã©ã¯ãã¯ã©ã¹ã®ãªãã¸ã§ã¯ãããç´æ¥ä½ããã¨ã¯ã§ããªããããã«ã¯ãå¤æ°ãé¢æ°ã®ä»®å¼æ°ãnewå¼ãªã©ã該å½ããã
struct abstract_class
{
virtual void f() = 0 ;
} ;
// ã¨ã©ã¼ãabstract_classã®ãªãã¸ã§ã¯ãã¯ä½ããªã
void f( abstract_class param )
{
abstract_class obj ; // ã¨ã©ã¼
new abstract_class ; // ã¨ã©ã¼
}
ã¢ãã¹ãã©ã¯ãã¯ã©ã¹ã¸ã®ãã¤ã³ã¿ã¼ããªãã¡ã¬ã³ã¹ã¯ä½¿ããã
struct abstract_class
{
virtual void f() = 0 ;
} ;
// OKããã¤ã³ã¿ã¼ã¨ãªãã¡ã¬ã³ã¹ã¯ãã
void f( abstract_class *, abstract_class & ) ;
ãã¥ã¢virtualé¢æ°ãç¶æ¿ãã¦ãã¦ããã¡ã¤ãã«ãªã¼ãã¼ã©ã¤ãã¼ããã¥ã¢virtualé¢æ°ã§ããå ´åããã¢ãã¹ãã©ã¯ãã¯ã©ã¹ã¨ãªããããã¯ä¾ãã°ãã¢ãã¹ãã©ã¯ãã¯ã©ã¹ããæ´¾çããã¦ããã¯ã©ã¹ãããã¥ã¢virtualé¢æ°ããªã¼ãã¼ã©ã¤ããã¦ããªãã£ãå ´åãªã©ãã該å½ããã
struct Base { virtual void f() = 0 ; } ;
struct Derived : Base { } ;
ãã®å ´åãDerivedããBaseã¨åãããã¢ãã¹ãã©ã¯ãã¯ã©ã¹ã«ãªãã
æ´¾çã¯ã©ã¹ã«ãã£ã¦ããã¥ã¢virtualé¢æ°ã§ã¯ãªãvirtualé¢æ°ããªã¼ãã¼ã©ã¤ããã¦ããã¥ã¢virtualé¢æ°ã«ãããã¨ãã§ããããã®å ´åãæ´¾çã¯ã©ã¹ã¯ã¢ãã¹ãã©ã¯ãã¯ã©ã¹ã¨ãªãã
struct Base { virtual void f() { } } ;
struct Derived : Base { virtual void f() = 0 ; } ;
int main()
{
Base b ; // OK
Derived d ; // ã¨ã©ã¼
}
ãã®ä¾ã§ã¯ãBaseã¯ã¢ãã¹ãã©ã¯ãã¯ã©ã¹ã§ã¯ãªããDerivedã¯ã¢ãã¹ãã©ã¯ãã¯ã©ã¹ã§ããã
æ§ç¯ä¸ãã¾ãã¯ç ´æ£ä¸ã®ã¢ãã¹ãã©ã¯ãã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ããã¹ãã©ã¯ã¿ã¼ã®ä¸ã§ããã¥ã¢virtualé¢æ°ãå¼ã³åºããå ´åã®æåã¯ãæªå®ç¾©ã§ããã
struct Base
{
virtual void f() = 0 ;
// ãã®é¢æ°ããBaseã®ã³ã³ã¹ãã©ã¯ã¿ã¼ããã¹ãã©ã¯ã¿ã¼ããå¼ã¶ã¨ã¨ã©ã¼
void g()
{ f() ; }
// ã³ã³ã¹ãã©ã¯ã¿ã¼
Base() // ã¨ã©ã¼ãæªå®ç¾©ã®æå
{ f() ; }
// ãã¹ãã©ã¯ã¿ã¼
~Base() // ã¨ã©ã¼ãæªå®ç¾©ã®æå
{ f() ; }
} ;
struct Derived : Base
{
virtual void f() { }
// Derivedã¯ã¢ãã¹ãã©ã¯ãã¯ã©ã¹ã§ã¯ãªãã®ã§ãåé¡ã¯ãªã
Derived() { f() ; }
~Derived() { f() ; }
} ;
ã¯ã©ã¹ã®ã¡ã³ãã¼ã¯ãprivateãprotectedãpublicã®ããããã®ã¢ã¯ã»ã¹æå®ãæã¤ã
privateãæå®ãããã¡ã³ãã¼ã¯ãåãã¯ã©ã¹ã®ã¡ã³ãã¼ã¨friendãã使ããã¨ãã§ããã
protectedãæå®ãããã¡ã³ãã¼ã¯ãåãã¯ã©ã¹ã¨ããã®ã¯ã©ã¹ããæ´¾çããã¦ããã¯ã©ã¹ã®ã¡ã³ãã¼ã¨friendãã使ããã¨ãã§ããã
publicã§ã¯ãã¡ã³ãã¼ã¯ã©ãããã§ãå¶éãªã使ããã
class Base
{
private :
int private_member ;
protected :
int protected_member ;
public :
int public_member ;
void f()
{
// åãã¯ã©ã¹ã®ã¡ã³ãã¼
private_member ; // OK
protected_member ; // OK
public_member ; // OK
}
} ;
void f()
{ // ã¯ã©ã¹å¤
Base base ;
base.private_member ; // ã¨ã©ã¼
base.protected_member ; // ã¨ã©ã¼
base.public_member ; // OK
}
class Derived : public Base
{
void f()
{
// æ´¾çã¯ã©ã¹ã®ã¡ã³ãã¼
private_member ; // ã¨ã©ã¼
protected_member ; // OK
public_member ; // OK
}
} ;
classãã¼ã¯ã¼ãã§å®ç¾©ãããã¯ã©ã¹ã®ã¡ã³ãã¼ã¯ãããã©ã«ãã§privateã«ãªããstructãã¼ã¯ã¼ãã§å®ç¾©ãããã¯ã©ã¹ã®ã¡ã³ãã¼ã¯ãããã©ã«ãã§publicã«ãªãã
// nameã¯private
class C { int name ; } ;
// nameã¯public
struct S { int name ; } ;
classã¨structãã¼ã¯ã¼ãã®éãã¯ãããã©ã«ãã®ã¢ã¯ã»ã¹æå®åãç°ãªãã ãã§ãããã¢ã¯ã»ã¹æå®åãæ示çã«è¨è¿°ããã¨ãclassã¨structãã¼ã¯ã¼ãã®éãã¯ãªããªãã
ã¢ã¯ã»ã¹æå®ã¯ãã¡ã³ãã¼ã®ç¨®é¡ãåãããååã«å¯¾ãã¦ä¸å¾ã«é©ç¨ããããã¢ã¯ã»ã¹æå®ã¯ãååæ¢ç´¢ã«å½±é¿ããããããã¨ã¯ãªãããã¨ãã¢ã¯ã»ã¹æå®ã«ãã£ã¦ä½¿ããªãååã§ãã£ã¦ããååã¯çºè¦ããããååãçºè¦ããããã¨èªä½ã¯ã¨ã©ã¼ã§ã¯ãªããã¢ã¯ã»ã¹æå®ã«ãã£ã¦ä½¿ããªãååã使ããã¨ããã¨ã¨ã©ã¼ã«ãªããä¾ãã°ãååãé¢æ°ã®ãªã¼ãã¼ãã¼ãã®ã»ããã§ãã£ãå ´åããªã¼ãã¼ãã¼ã解決ãããçµæã®ååã«å¯¾ããã¢ã¯ã»ã¹æå®ãé©ç¨ãããã
class X
{
private :
void f( int ) { }
public :
void f( double ) { }
} ;
int main()
{
X x ;
// ã¨ã©ã¼ãprivateã¡ã³ãã¼ã«ã¯ã¢ã¯ã»ã¹åºæ¥ãªã
// ãªã¼ãã¼ãã¼ã解決ã®çµæã¯X::f( int )
x.f( 0 ) ;
// OKãX::f( double )ãå¼ã°ãã
x.f( 0.0 ) ;
}
ãã®ä¾ã§ã¯ãXã®ã¡ã³ãã¼fã«å¯¾ãã¦ãf(0)ã¨ããé¢æ°å¼ã³åºãã®å¼ãé©ç¨ãã¦ãããã¢ã¯ã»ã¹æå®ã¯ååæ¢ç´¢ã«å½±é¿ããããããã¨ã¯ãªãã®ã§ãé¢æ°ãªã¼ãã¼ãã¼ãã®ã»ããã¨ãã¦ãX::f(int)ã¨ãX::f(double)ã¨ããååãçºè¦ããããããã¦ããªã¼ãã¼ãã¼ã解決ã«ãã£ã¦ãX::f(int)ãæé©ãªé¢æ°ã¨ãã¦é¸ã°ãããã¢ã¯ã»ã¹æå®ã®ãã§ãã¯ã¯ããªã¼ãã¼ãã¼ã解決ã®å¾ã«è¡ãããããã®å ´åãX::f(int)ã¯privateã¡ã³ãã¼ãªã®ã§ãXã®ã¡ã³ãã¼ã§ãfriendé¢æ°ã§ããªãmainé¢æ°ããå¼ã³åºããã¨ã¯ã§ããªãã
ã¯ã©ã¹ã®ã¡ã³ãã¼ã®ã¢ã¯ã»ã¹æå®ã¯ãã©ãã«ã«ã¢ã¯ã»ã¹æå®åï¼Access specifiersï¼ãè¨è¿°ãããã¨ã§æå®ããã
ã¢ã¯ã»ã¹æå®å : ã¡ã³ãã¼æå®opt
ã¢ã¯ã»ã¹æå® :
private
protected
public
ã¢ã¯ã»ã¹æå®åã¨ã¯ãprivateãprotectedãpublicã®ããããã§ãããã¢ã¯ã»ã¹æå®åãç¾ããå ´æããã次ã®ã¢ã¯ã»ã¹æå®åããã¯ã©ã¹å®ç¾©ã®çµäºã¾ã§ã®éã®ã¡ã³ãã¼ããã¢ã¯ã»ã¹æå®åã®å½±é¿ãåããã
class X
{
int a ; // ããã©ã«ãã®private
public :
int b ; // public
int c ; // public
protected :
int d ; // protected
private :
int e ; // private
} ;
ã¢ã¯ã»ã¹æå®åã«ã¯ãé çªã使ç¨å¯è½ãªåæ°ã®å¶éã¯ãªãã好ããªé çªã§ãä½åº¦ã§ãæå®ã§ããã
class X
{
public :
public :
protected :
public :
public :
private :
} ;
ããã¯ã©ã¹ããå¥ã®ã¯ã©ã¹ã®åºæ¬ã¯ã©ã¹ã¨ããã¨ããããããã®ã¢ã¯ã»ã¹æå®åãæå®ããã
class Base { } ;
class Derived_by_public : public Base { } ; // publicæ´¾ç
class Derived_by_protected : protected Base { } ; // protectedæ´¾ç
class Derived_by_private : private Base { } ; // privateæ´¾ç
ã¢ã¯ã»ã¹æå®åãpublicã®å ´åãåºæ¬ã¯ã©ã¹ã®publicã¡ã³ãã¼ã¯ãæ´¾çã¯ã©ã¹ã®publicã¡ã³ãã¼ã¨ãã¦ã¢ã¯ã»ã¹å¯è½ã«ãªããåºæ¬ã¯ã©ã¹ã®protectedã¡ã³ãã¼ã¯ãæ´¾çã¯ã©ã¹ã®protectedã¡ã³ãã¼ã¨ãã¦ã¢ã¯ã»ã¹å¯è½ã«ãªãã
class Base
{
public :
int public_member ;
protected :
int protected_member ;
} ;
class Derived : public Base
{
void f()
{
public_member ; // OK
protected_member ; // OK
}
} ;
int main()
{
Derived d ;
d.public_member ; // OK
}
ã¢ã¯ã»ã¹æå®åãprotectedã®å ´åãåºæ¬ã¯ã©ã¹ã®publicã¨protectedã¡ã³ãã¼ã¯ãæ´¾çã¯ã©ã¹ã®protectedã¡ã³ãã¼ã¨ãã¦ã¢ã¯ã»ã¹å¯è½ã«ãªãã
class Base
{
public :
int public_member ;
protected :
int protected_member ;
} ;
class Derived : protected Base
{
void f()
{
public_member ; // OKããã ãprotectedã¡ã³ãã¼
protected_member ; // OK
}
} ;
int main()
{
Derived d ;
d.public_member ; // ã¨ã©ã¼ãDerivedããã¯ãprotectedã¡ã³ãã¼ã§ãã
}
ã¢ã¯ã»ã¹æå®åãprivateã®å ´åãåºæ¬ã¯ã©ã¹ã®publicã¨protectedã¡ã³ãã¼ã¯ãæ´¾çã¯ã©ã¹ã®privateã¡ã³ãã¼ã¨ãã¦ã¢ã¯ã»ã¹å¯è½ã«ãªãã
class Base
{
public :
int public_member ;
protected :
int protected_member ;
} ;
class Derived : private Base
{
void f()
{
public_member ; // OKããã ããprivateã¡ã³ãã¼
protected_member ; // OKããã ããprivateã¡ã³ãã¼
}
} ;
class Derived2 : public Derived
{
void f()
{
public_member ; // ã¨ã©ã¼ãåºæ¬ã¯ã©ã¹ã®privateã¡ã³ãã¼ã«ã¯ã¢ã¯ã»ã¹ã§ããªã
protected_member ; // ã¨ã©ã¼ãåºæ¬ã¯ã©ã¹ã®privateã¡ã³ãã¼ã«ã¯ã¢ã¯ã»ã¹ã§ããªã
}
} ;
int main()
{
Derived d ;
d.public_member ; // ã¨ã©ã¼ãDerivedããã¯ãprivateã¡ã³ãã¼ã§ãã
}
åºæ¬ã¯ã©ã¹ã«ã¢ã¯ã»ã¹æå®åãæå®ããªãã£ãå ´åãstructãã¼ã¯ã¼ãã§å®£è¨ãããã¯ã©ã¹ã¯ãããã©ã«ãã§publicã«ãclassãã¼ã¯ã¼ãã§å®£è¨ãããã¯ã©ã¹ã¯ãããã©ã«ãã§privateã«ãªãã
struct Base { } ;
// ããã©ã«ãã®publicæ´¾ç
struct D1 : Base { } ;
// ããã©ã«ãã®privateæ´¾ç
class D2 : Base { } ;
ã©ã®ã¢ã¯ã»ã¹æå®åãæå®ãã¦æ´¾çãã¦ããåºæ¬ã¯ã©ã¹ã®privateã¡ã³ãã¼ãæ´¾çã¯ã©ã¹ãã使ããã¨ã¯ã§ããªããã¯ã©ã¹Aããprivateæ´¾çããã¯ã©ã¹Bããæ´¾çãã¦ããã¯ã©ã¹Cã§ã¯ãã¯ã©ã¹Aã®ã¡ã³ãã¼ã¯ä½¿ããªãã®ãããã®çç±ã«ããã
// classãã¼ã¯ã¼ãã§å®£è¨ãããã¯ã©ã¹ã®ã¡ã³ãã¼ã¯ããã©ã«ãã§private
class Base { int private_member ; } ;
class Derived : public Base
{
// ã©ã®ã¢ã¯ã»ã¹æå®ãç¨ãã¦ããåºæ¬ã¯ã©ã¹ã®private_memberã¯ä½¿ããªã
} ;
struct A { int public_member ; } ;
class B : private A { } ;
class C : public B
{
// ã¯ã©ã¹Bã¯ãã¯ã©ã¹Aããprivateæ´¾çãã¦ãããããããã§ã¯A::public_memberã¯ä½¿ããªãã
} ;
ã¯ã©ã¹åèªä½ããã¯ã©ã¹ã¹ã³ã¼ãå
ã®ååã¨ãã¦æ±ããããã¯ã©ã¹Aããprivateæ´¾çããã¯ã©ã¹Bããæ´¾çãã¦ããã¯ã©ã¹Cã§ã¯ãã¯ã©ã¹Aã®ã¯ã©ã¹åèªä½ãprivateã¡ã³ãã¼ã«ãªã£ã¦ãã¾ãã
// ã°ãã¼ãã«åå空éã®ã¹ã³ã¼ã
struct A { } ;
class B : private A { } ;
class C : public B
{
void f()
{
A a1 ; // ã¨ã©ã¼ãååAã¯ãåºæ¬ã¯ã©ã¹ã®privateã¡ã³ãã¼ã®A
::A a2 ; // OKãåå::Aã¯ãã°ãã¼ãã«åå空éã¹ã³ã¼ãå
ã®A
}
} ;
ãã®ä¾ã§ã¯ãã¯ã©ã¹Cã®ã¹ã³ã¼ãå
ã§ãé修飾åAã«å¯¾ãã¦ãã¯ã©ã¹åAãçºè¦ããã¦ãã¾ãã®ã§ãã¨ã©ã¼ã«ãªããã¯ã©ã¹Cã®ä¸ã§ã¯ã©ã¹Aã使ãããå ´åãæ示çãªä¿®é£¾ãå¿
è¦ã§ããã
ã¢ã¯ã»ã¹æå®åã¯ãstaticã¡ã³ãã¼ã«ãé©ç¨ããããpublicãªstaticã¡ã³ãã¼ãæã¤ã¯ã©ã¹ããprotectedãprivateã§æ´¾çããã¨ãåºæ¬ã¯ã©ã¹ããã¯ã¢ã¯ã»ã¹ã§ããããæ´¾çã¯ã©ã¹ãä»ãã¦ã¢ã¯ã»ã¹ã§ããªããªã£ã¦ãã¾ããã¨ãããã
// ã°ãã¼ãã«åå空éã®ã¹ã³ã¼ã
struct A { static int data ; } ;
int A::data ;
class B : private A { } ;
class C : public B
{
void f()
{
data ; // ã¨ã©ã¼
::A::data ; // OK
}
} ;
ã¯ã©ã¹Cããã¯ãåådataã¯ãåºæ¬ã¯ã©ã¹Aã®ã¡ã³ãã¼dataã¨ãã¦çºè¦ãããã®ã§ãã¢ã¯ã»ã¹ã§ããªããããããã¯ã©ã¹Aèªä½ã¯ãåå空éã«åå¨ããã®ã§ãæ示çãªä¿®é£¾ã使ãã°ãã¢ã¯ã»ã¹ã§ããã
protectedã®å ´åãfriendã§ã¯ãªãã¯ã©ã¹å¤é¨ã®é¢æ°ããã¢ã¯ã»ã¹ã§ããªããªãã
struct A { static int data ; }
int A::data ;
class B : protected A { } ;
int main()
{
B::data ; // ã¨ã©ã¼
A::data ; // OK
}
ããã§ã¯ãB::dataã¨A::dataã¯ãã©ã¡ããåããªãã¸ã§ã¯ããæãã¦ããããã¢ã¯ã»ã¹æå®ã®éãã«ãããB::dataã¨ãã修飾åã§ã¯ãã¯ã©ã¹Bã®friendã§ã¯ãªãmainé¢æ°ããã¢ã¯ã»ã¹ãããã¨ãã§ããªãã
åºæ¬ã¯ã©ã¹ã«ã¢ã¯ã»ã¹å¯è½ã§ããå ´åãæ´¾çã¯ã©ã¹ã¸ã®ãã¤ã³ã¿ã¼åãããåºæ¬ã¯ã©ã¹ã¸ã®ãã¤ã³ã¿ã¼åã«åå¤æã§ããã
class A { } ;
class B : public A { } ;
class C : protected A
{
void f()
{
static_cast< A * >( this ) ; // OKãã¢ã¯ã»ã¹å¯è½
}
} ;
int main()
{
B b ;
static_cast< A * >( &b ) ; // OKãã¢ã¯ã»ã¹å¯è½
C c ;
static_cast< A * >( &c ) ; // ã¨ã©ã¼ãmainé¢æ°ããã¯ãprotectedã¡ã³ãã¼ã«ã¢ã¯ã»ã¹ã§ããªã
}
ã¯ã©ã¹ã¯friendã宣è¨ãããã¨ãã§ãããfriendã宣è¨ããã«ã¯ãfriendæå®åã使ããã¯ã©ã¹ã®friendã¨ãã¦å®£è¨ã§ãããã®ã¯ãé¢æ°ãã¯ã©ã¹ã§ãããã¯ã©ã¹ã®friendã¯ãã¯ã©ã¹ã®privateã¨protectedã¡ã³ãã¼ã«ã¢ã¯ã»ã¹ã§ããã
class X
{
private :
typedef int type ; // privateã¡ã³ãã¼
friend void f() ; // friendé¢æ°
friend class Y ; // friendã¯ã©ã¹
} ;
void f()
{
X::type a ; // OKãé¢æ°void f(void)ã¯Xã®friend
}
class Y
{
X::type member ; // OKãã¯ã©ã¹Yã¯Xã®friend
void f()
{
X::type member ; // OKãã¯ã©ã¹Yã¯Xã®friend
}
} ;
friendã¯ã©ã¹ã®å®£è¨ã¯ãfriendæå®åã«ç¶ãã¦ãè¤éåæå®åãåç´åæå®åãtypenameæå®åï¼åå解決ãåç
§ï¼ã®ããããã宣è¨ããªããã°ãªããªãã
è¤éåæå®åã¯ãæãåãããããã
class X
{
friend class Y ;
friend struct Z ;
} ;
è¤éåæå®åã使ãå ´åãã¯ã©ã¹ãããããã宣è¨ãã¦ããå¿
è¦ã¯ãªããååãã¯ã©ã¹ã§ãããã¨ãããã®æç¹ã§å®£è¨ãããããã ã
åç´åæå®åã«ååã使ãå ´åã¯ããããã以åã«ãã¯ã©ã¹ã宣è¨ãã¦ããå¿
è¦ãããã
class Y ; // Yãã¯ã©ã¹ã¨ãã¦å®£è¨
class X
{
friend Y ; // OKãYã¯ã¯ã©ã¹ã§ãã
friend Z ; // ã¨ã©ã¼ãååZã¯è¦ã¤ãããªã
friend class A ; // OKãAã¯ã¯ã©ã¹ã¨ãã¦ãããã§å®£è¨ããã¦ãã
} ;
ãããããååã宣è¨ããã¦ããªãå ´åã¯ãã¨ã©ã¼ã¨ãªãã
åç´åæå®åã«ãã³ãã¬ã¼ãåã使ããã¨ãã§ããã
template < typename T >
class X
{
friend T ; // OK
} ;
typenameæå®åãæå®ããå ´åã¯ã以ä¸ã®ããã«ãªãã
template < typename T >
class X
{
friend typename T::type ;
} ;
T::typeã¯ãä¾ååãåã¨ãã¦ä½¿ã£ã¦ããã®ã§ãtypenameãå¿
è¦ã§ããã
ãããåæå®åãã¯ã©ã¹åã§ã¯ãªãå ´åãåã«ç¡è¦ããããããã¯ããã³ãã¬ã¼ãã³ã¼ããæ¸ãã¨ãã«ä¾¿å©ã§ããã
template < typename T >
class X
{
friend T ;
} ;
X<int> x ; // OKãfriend宣è¨ã¯ç¡è¦ããã
template < typename T >
class Y
{
friend typename T::type ;
} ;
struct Z { typedef int type ; } ;
Y<Z> y ; // OKãfriend宣è¨ã¯ç¡è¦ããã
ç¡è¦ãããã®ã¯ãããã¾ã§ãåæå®åãã¯ã©ã¹åã§ã¯ãªãã£ãå ´åã§ããããã§ã«èª¬æããããã«ãåç´åæå®åã§ãååãè¦ã¤ãããªãã£ãå ´åã¯ãã¨ã©ã¼ã«ãªãã
friendé¢æ°ã®å®£è¨ã¯ãé常éãã®é¢æ°ã®å®£è¨ã®ææ³ã«ãfriendæå®åãè¨è¿°ãããåæ¹å®£è¨ã¯å¿
é ã§ã¯ãªããfriendé¢æ°ã«ã¯ãã¹ãã¬ã¼ã¸ã¯ã©ã¹æå®åãè¨è¿°ãããã¨ã¯ã§ããªãã
class X
{
friend void f() ;
friend int g( int, int, int ) ;
friend X operator + ( X const &, X const & ) ;
} ;
friendé¢æ°ã¨ãã¦å®£è¨ãããé¢æ°ããªã¼ãã¼ãã¼ãããã¦ããå ´åã§ããfriendé¢æ°ã¨ãã¦å®£è¨ããã·ã°ããã£ã®é¢æ°ãããfriendã«ã¯ãªããªãã
void f( int ) ;
void f( double ) ;
class X
{
friend void f( int ) ;
} ;
ãã®ä¾ã§ã¯ãvoid f(int)ã®ã¿ããXã®friendé¢æ°ã«ãªããvoid f(double)ã¯ãfriendé¢æ°ã«ã¯ãªããªãã
ä»ã®ã¯ã©ã¹ã®ã¡ã³ãã¼é¢æ°ããfriendé¢æ°ã¨ãã¦å®£è¨ã§ãããã¡ã³ãã¼é¢æ°ã«ã¯ãã³ã³ã¹ãã©ã¯ã¿ã¼ããã¹ãã©ã¯ã¿ã¼ãå«ã¾ããã
class X ; // ååXãã¯ã©ã¹åã¨ãã¦å®£è¨
class Y
{
public :
void f( ) ; // ã¡ã³ãã¼é¢æ°
Y & operator = ( X const & ) ; // 代å
¥æ¼ç®å
Y() ; // ã³ã³ã¹ãã©ã¯ã¿ã¼
~Y() ; // ãã¹ãã©ã¯ã¿ã¼
} ;
class X
{
// 以ä¸4è¡ã¯ããã¹ã¦æ£ããfriend宣è¨
friend void Y::f( ) ;
friend Y & Y::operator = ( X const & ) ;
friend Y::Y() ;
friend Y::~Y() ;
} ;
friend宣è¨èªä½ã«ã¯ãã¢ã¯ã»ã¹æå®ã¯é©ç¨ãããªãããã ããfriend宣è¨ã®ä¸ã§ã¢ã¯ã»ã¹ã§ããªãååã使ããã¨ã¯ã§ããªãã
class Y
{
private :
void f( ) ; // privateã¡ã³ãã¼
} ;
class X
{
// ã¨ã©ã¼ãYã®privateã¡ã³ãã¼ã«ã¯ã¢ã¯ã»ã¹åºæ¥ãªã
// friend宣è¨ã®ä¸ã®ååã®ä½¿ç¨ã«ã¯ãã¢ã¯ã»ã¹æå®ãå½±é¿ãã
friend void Y::f() ;
// ã¢ã¯ã»ã¹æå®ã¯ãfriend宣è¨èªä½ã«å½±é¿ãåã¼ããªã
// 以ä¸3è¡ã®friend宣è¨ã«ãã¢ã¯ã»ã¹æå®ã¯ä½ã®æå³ããªããªã
private :
friend void f() ;
protected :
friend void g() ;
public :
friend void h() ;
} ;
Y::fã¯privateã¡ã³ãã¼ãªã®ã§ãXããã¯ã¢ã¯ã»ã¹ã§ããªããXã®friend宣è¨ã¯ãé¢æ°f, g, hããXã®friendã¨ãã¦å®£è¨ãã¦ãããããã®å®£è¨ã«ãXã®ã¢ã¯ã»ã¹æå®ã¯ä½ã®å¹æãä¸ããªãã
friend宣è¨ã¯ãå®ã¯é¢æ°ãå®ç¾©ãããã¨ãã§ããã
class X
{
friend void f() { } // é¢æ°ã®å®ç¾©
} ;
friend宣è¨ã§å®ç¾©ãããé¢æ°ã¯ãã¯ã©ã¹ãå®ç¾©ããã¦ããåå空éã¹ã³ã¼ãã®é¢æ°ã«ãªããã¯ã©ã¹ã®ã¡ã³ãã¼é¢æ°ã«ã¯ãªããªãããã ããfriend宣è¨ã§å®ç¾©ãããé¢æ°ã¯ãADLã使ããªããã°ãå¼ã³åºããã¨ã¯ã§ããªããé修飾ååæ¢ç´¢ãã修飾ååæ¢ç´¢ã§ãé¢æ°åãåç
§ããæ¹æ³ã¯ãªãã
// ã°ãã¼ãã«åå空éã®ã¹ã³ã¼ã
class X
{
// fã¯ã¡ã³ãã¼é¢æ°ã§ã¯ãªã
// ã¯ã©ã¹Xã®å®ç¾©ããã¦ããã°ãã¼ãã«åå空éã®ã¹ã³ã¼ãå
ã®é¢æ°
friend void f( X ) { }
// gã¯ã¡ã³ãã¼é¢æ°ã§ã¯ãªã
// gãå¼ã³åºãæ¹æ³ã¯åå¨ããªã
friend void g() { }
} ;
int main()
{
X x ;
f(x) ; // OKãADLã«ããååæ¢ç´¢
(f)(x) ; // ã¨ã©ã¼ãæ¬å¼§ãADLãé»å®³ãããADLãåããªãã®ã§ååfãè¦ã¤ãããªã
::f(x) ; // ã¨ã©ã¼ãååfãè¦ã¤ãããªã
g() ; // ã¨ã©ã¼ãåågãè¦ã¤ãããªã
}
ãã®ããã«ãé常ã®ååæ¢ç´¢ã§ã¯é¢æ°åãè¦ã¤ãããªãã¨ããåé¡ããããããfriend宣è¨å
ã§ã®é¢æ°å®ç¾©ã¯ãè¡ãã¹ãã§ã¯ãªãã
friendã«ãã£ã¦å®£è¨ãããé¢æ°ã¯ãåæ¹å®£è¨ããã¦ããªãå ´åãå¤é¨ãªã³ã±ã¼ã¸ãæã¤ãåæ¹å®£è¨ããã¦ããå ´åããªã³ã±ã¼ã¸ã¯åæ¹å®£è¨ã«å¾ãã
inline void g() ; // åæ¹å®£è¨ãé¢æ°gã¯å
é¨ãªã³ã±ã¼ã¸ãæã¤
class X
{
friend void f() ; // é¢æ°fã¯å¤é¨ãªã³ã±ã¼ã¸ãæã¤
friend void g() ; // é¢æ°gã¯å
é¨ãªã³ã±ã¼ã¸ãæã¤
} ;
// å®ç¾©
void f() { } // å¤é¨ãªã³ã±ã¼ã¸
inline void g() { }
friend宣è¨ã¯ãæ´¾çããããã¨ã¯ãªããã¾ããããã¯ã©ã¹ã®friendã®friendã¯ãããã¯ã©ã¹ã®friendã§ã¯ãªããã¤ã¾ããåéã®åéã¯ãåéã§ã¯ãªãã
class A
{
private :
typedef int type ;
friend class B ;
} ;
class B
{
// OKãBã¯Aã®friend
typedef A::type type ;
friend class C ;
} ;
class C
{
// ã¨ã©ã¼ãBã¯Aã®friendã§ãããCã¯Bã®friendã§ããã
// Cã¯ãAããã¿ã¦ãfriendã®friendã«ãããã
// ããããCã¯Aã®friendã§ã¯ãªãã
typedef A::type type ;
} ;
class D : public B
{
// ã¨ã©ã¼ãDã¯Bããæ´¾çãã¦ãããBã¯Aã®friendã§ããã
// ããããDã¯Aã®friendã§ã¯ãªã
typedef A::type type ;
} ;
ãã¼ã«ã«ã¯ã©ã¹ã®ä¸ã§friend宣è¨ã§ãé修飾åã使ã£ãå ´åãååæ¢ç´¢ã«ããã¦ããã¼ã«ã«ã¯ã©ã¹ã®å®ç¾©ããã¦ããé¢æ°å¤ã®ã¹ã³ã¼ãã¯èæ
®ãããªããfriendé¢æ°ã宣è¨ããå ´åã対象ã®é¢æ°ã¯friend宣è¨ã«å
ç«ã£ã¦å®£è¨ããã¦ããªããã°ãªããªããfriendã¯ã©ã¹ã宣è¨ããå ´åãã¯ã©ã¹åã¯ãã¼ã«ã«ã¯ã©ã¹ã®ååã§ããã¨è§£éãããã
class A ; // ::A
void B() ; // ::B
void f()
{
// é¢æ°ã®åæ¹å®£è¨ã¯é¢æ°å
ã§ãå¯è½
void C( void ) ; // å®ç¾©ã¯å¥ã®å ´æ
class Y ; // ãã¼ã«ã«ã¯ã©ã¹Yã®å®£è¨
// ãã¼ã«ã«ã¯ã©ã¹Xã®å®ç¾©
class X
{
friend class A ; // OKããã ãã::Aã§ã¯ãªãããã¼ã«ã«ã¯ã©ã¹ã®A
friend class ::A ; // OKã::A
friend class Y ; // OKããã ããã¼ã«ã«ã¯ã©ã¹Y
friend void B() ; // ã¨ã©ã¼ãBã¯å®£è¨ããã¦ããªãã::Bã¯èæ
®ãããªã
friend void C() ; // OKãé¢æ°å
ã®åæ¹å®£è¨ã«ããååãçºè¦
} ;
}
friend宣è¨ã¨ãã³ãã¬ã¼ãã®çµã¿åããã«ã¤ãã¦ã¯ããã³ãã¬ã¼ã宣è¨ã®friendãåç
§ã
protectedã¡ã³ãã¼ã¯ãfriendããã¡ã³ãã¼ã®å®£è¨ãããã¯ã©ã¹ããã¯ã©ã¹ããæ´¾çãã¦ããã¯ã©ã¹ããã¢ã¯ã»ã¹ãããã¨ãã§ããã
void g() ;
class Base
{
friend void g() ;
protected :
int member ;
} ;
void f()
{
Base base ;
base.member ; // ã¨ã©ã¼ãprotectedã¡ã³ãã¼
}
void g()
{
Base base ;
base.member ; // OKãgã¯Baseã®friend
}
class Derived : protected Base
{
void f()
{
member ; // OKãDerivedã¯Baseããæ´¾çãã¦ãã
}
} ;
virtualé¢æ°ã¸ã®ã¢ã¯ã»ã¹ã¯ãvirtualé¢æ°ã®å®£è¨ã«ãã£ã¦æ±ºå®ããããvirtualé¢æ°ã®ãªã¼ãã¼ã©ã¤ãã«ã¯å½±é¿ãããªãã
class Base
{
public :
virtual void f() { }
} ;
class Derived : public Base
{
private :
void f() { } // Base::fããªã¼ãã¼ã©ã¤ã
} ;
int main()
{
Derived d ;
d.f() ; // ã¨ã©ã¼ãDerived::fã¯privateã¡ã³ãã¼
Base & ref = d ;
ref.f() ; // OKãDerived::fãå¼ã¶
}
Derived::fã¯privateã¡ã³ãã¼ãªã®ã§ãé¢æ°mainããå¼ã³åºããã¨ã¯ã§ããªããããããBase::fã¯publicã¡ã³ãã¼ã§ãããBase::fã¯virtualé¢æ°ãªã®ã§ãå¼ã³åºãé¢æ°ã¯ãå®è¡æã®ãªãã¸ã§ã¯ãã®åã«ãã£ã¦æ±ºå®ãããããã®æããªã¼ãã¼ã©ã¤ãããvirtualé¢æ°ã®ã¢ã¯ã»ã¹æå®ã¯ãèæ
®ãããªããBase::fã®ã¢ã¯ã»ã¹æå®ã®ã¿ãèæ
®ãããããã®ä¾ã§ã¯ãé¢æ°mainãããDerived::fãç´æ¥å¼ã³åºããã¨ã¯ã§ããªãããBaseã¸ã®ãªãã¡ã¬ã³ã¹ããã¤ã³ã¿ã¼ãçµç±ããã°ãå¼ã³åºããã¨ãã§ããã
virtualé¢æ°å¼ã³åºãã®ã¢ã¯ã»ã¹ãã§ãã¯ã¯ãå¼ã³åºãéã®å¼ã®åã«ãã£ã¦ãéçã«æ±ºå®ããããåºæ¬ã¯ã©ã¹ã§publicã¡ã³ãã¼ã¨ãã¦å®£è¨ããã¦ããvirtualé¢æ°ããæ´¾çã¯ã©ã¹ã§protectedãprivateã«ãã¦ããåºæ¬ã¯ã©ã¹çµç±ã§å¼ã³åºããã¨ãã§ããã
å¤éæ´¾çã«ãã£ã¦ãåºæ¬ã¯ã©ã¹ã®ã¡ã³ãã¼ã«å¯¾ãã¦ãè¤æ°ã®ã¢ã¯ã»ã¹ãã¹ãå½¢æããã¦ããå ´åãã¢ã¯ã»ã¹å¯è½ãªãã¹ãçµç±ãã¦ã¢ã¯ã»ã¹ã許å¯ãããã
class Base
{
public :
void f() { }
} ;
class D1 : private virtual Base { } ;
class D2 : public virtual Base { } ;
class Derived : public D1, public D2
{
void f()
{
Base::f() ; // OKãD2ãçµç±ãã¦ã¢ã¯ã»ã¹ãã
}
} ;
D1ã¯Baseãprivateæ´¾çãã¦ããã®ã§ãDerivedããD1çµç±ã§ã¯ãBaseã«ã¢ã¯ã»ã¹ã§ããªããããããD2çµç±ã§ã¢ã¯ã»ã¹ã§ããã
ãã¹ããããã¯ã©ã¹ããã¯ã©ã¹ã®ã¡ã³ãã¼ã§ããã®ã§ãä»ã®ã¡ã³ãã¼ã¨ã¢ã¯ã»ã¹æ¨©éãæã¤ã
class Outer
{
private :
typedef int type ; // privateã¡ã³ãã¼
class Inner
{
Outer::type data ; // OKãInnerã¯Outerã®ã¡ã³ãã¼
} ;
} ;
Outerã«ãã¹ããããã¯ã©ã¹Innerã¯ãOuterã®ã¡ã³ãã¼ãªã®ã§ãOuterã®privateã¡ã³ãã¼ã«ã¢ã¯ã»ã¹ãããã¨ãã§ããã
ãã ãããã¹ããããã¯ã©ã¹ãã¡ã³ãã¼ã¨ãã¦æã¤ã¯ã©ã¹ã¯ããã¹ããããã¯ã©ã¹ã«å¯¾ãã¦ãç¹å¥ãªã¢ã¯ã»ã¹æ¨©éã¯æããªãã
class Outer
{
class Inner
{
private :
typedef int type ; // privateã¡ã³ãã¼
} ;
void f()
{
Inner::type x ; // ã¨ã©ã¼ãInner::typeã¯privateã¡ã³ãã¼
}
} ;
ãã®ä¾ã§ã¯ãOuterã¯ãInnerã®privateã¡ã³ãã¼ã«ã¯ã¢ã¯ã»ã¹ã§ããªãã
ã¯ã©ã¹ã®ã¡ã³ãã¼é¢æ°ã®ä¸ã§ããç¹å¥ãªæ±ããåããã¡ã³ãã¼é¢æ°ãåå¨ãããããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ãã³ãã¼ä»£å
¥æ¼ç®åãã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ãã ã¼ã代å
¥æ¼ç®åããã¹ãã©ã¯ã¿ã¼ã¯ãç¹å¥ãªã¡ã³ãã¼é¢æ°ï¼special member functionsï¼ã§ããã
ãããã®ã¡ã³ãã¼é¢æ°ãæ示çã«å®ç¾©ããªãå ´åãæé»ã®ã¡ã³ãã¼é¢æ°ãçæããããæé»ã«çæãããç¹å¥ãªã¡ã³ãã¼é¢æ°ã¯ãæ示çã«ä½¿ç¨ãããã¨ãã§ããã
#include <utility>
struct X { } ;
int main()
{
X x1 ; // ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼
X x2( x1 ) ; // ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼
X x3( std::move(x1) ) ; // ã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼
x2 = x1 ; // ã³ãã¼ä»£å
¥æ¼ç®å
x2 = std::move( x1 ) ; // ã ã¼ã代å
¥æ¼ç®å
x2.operator=( x1 ) ; // ã¡ã³ãã¼é¢æ°ã®æ示çãªä½¿ç¨ãx2 = x1ã¨åç
}
ã¯ã©ã¹Xã¯ãç¹å¥ãªã¡ã³ãã¼é¢æ°ãä¸åå®ç¾©ãã¦ããªããããããç¹å¥ãªã¡ã³ãã¼é¢æ°ã¯ãæé»ã®ãã¡ã«çæãããã®ã§ãã¯ã©ã¹Xã®ãªãã¸ã§ã¯ããåæåãç ´æ£ã§ããããã³ãã¼ãã ã¼ããã§ããã
ã¦ã¼ã¶ã¼å®ç¾©ããã¦ããªãç¹å¥ãªã¡ã³ãã¼é¢æ°ã¯ãæ¡ä»¶æ¬¡ç¬¬ã§ãæé»ã«deleteå®ç¾©ããããã¨ãããããã®ãããªã¯ã©ã¹ã®ç¹å¥ãªã¡ã³ãã¼é¢æ°ã使ãããå ´åã¯ãã¦ã¼ã¶ã¼å®ç¾©ããªããã°ãªããªãã
struct X
{
int & member ;
// ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯æé»ã«deleteå®ç¾©ããã
// X() = delete ; ãæé»ã«å®£è¨ããã
} ;
int data ; // ã°ãã¼ãã«å¤æ°
struct Y
{
int & member ;
Y() : member(data) { }
} ;
int main()
{
X x ; // ã¨ã©ã¼ãããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯deleteå®ç¾©ããã¦ãã
Y y ; // OKãã¦ã¼ã¶ã¼å®ç¾©ã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ããã
}
ç¹å¥ãªã¡ã³ãã¼é¢æ°ãæ示çã«å®£è¨ãå®ç¾©ãããã¨ã§ãã¯ã©ã¹ãã©ã®ããã«çæãç ´æ£ãã³ãã¼ãã ã¼ãããããè¨è¿°ã§ãããã¾ãããããã®æä½ããæ示çã«ç¦æ¢ãããã¨ãã§ããã
struct X
{
// ã³ãã¼ãã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ãdeleteå®ç¾©
X( X const & ) = delete ;
X( X && ) = delete ;
// ã³ãã¼ãã ã¼ã代å
¥æ¼ç®åãdeleteå®ç¾©
X & operator = ( X const & ) = delete ;
X & operator = ( X && ) = delete ;
} ;
ãã®ä¾ã§ã¯ãã³ãã¼ãã ã¼ããã§ããªãã¯ã©ã¹ãå®ç¾©ãã¦ããã
ç¹å¥ãªã¡ã³ãã¼é¢æ°ããã¢ã¯ã»ã¹æå®ã®å½±é¿ãåããã
class X
{
public :
X( int ) { }
private :
X( double ) { }
} ;
int main()
{
X a( 0 ) ; // OKãX::X(int)ã¯publicã¡ã³ãã¼
X b( 0.0 ) ; // ã¨ã©ã¼ãX::X(double)ã¯privateã¡ã³ãã¼
}
ãã®ä¾ã§ã¯ãX::X(int)ã¯publicã¡ã³ãã¼ãªã®ã§ãmainé¢æ°ããã¢ã¯ã»ã¹ã§ããããX::X(double)ã¯ãprivateã¡ã³ãã¼ãªã®ã§ãmainé¢æ°ããã¢ã¯ã»ã¹ã§ããªãããã®çµæãå¤æ°bã®å®ç¾©ã¯ã¨ã©ã¼ã¨ãªãã
ã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ååãæããªããã³ã³ã¹ãã©ã¯ã¿ã¼ã®å®£è¨ã«ã¯ãç¹å¥ãªææ³ãç¨ããããã
é¢æ°æå®åãããã¯constexpr ã¯ã©ã¹å ä»®å¼æ°ãªã¹ã
struct X
{
X() ; // ã³ã³ã¹ãã©ã¯ã¿ã¼ã®å®£è¨
} ;
X::X() { } // ã³ã³ã¹ãã©ã¯ã¿ã¼ã®å®ç¾©
ã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ãã¯ã©ã¹åã®ãªãã¸ã§ã¯ããåæåããã®ã«ç¨ããããã
ã³ã³ã¹ãã©ã¯ã¿ã¼ã®ã¯ã©ã¹åã«ãtypedefåãç¨ãããã¨ã¯ã§ããªãã
ã³ã³ã¹ãã©ã¯ã¿ã¼ã«ãvirtualæå®åãstaticæå®åãæå®ãããã¨ã¯ã§ããªããè¦ç´ããã°ãã³ã³ã¹ãã©ã¯ã¿ã¼ã«ä½¿ç¨å¯è½ãªæå®åã¯ãinlineãexplicitãconstexprã§ãããã³ã³ã¹ãã©ã¯ã¿ã¼ãCV修飾ãããã¨ã¯ã§ããªãããã ããã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ãCV修飾ããããªãã¸ã§ã¯ãã®åæåã«å¯¾ãã¦ããå¼ã³åºãããããªãã¸ã§ã¯ãã®CV修飾åã¯ãæ§ç¯ä¸ã®ãªãã¸ã§ã¯ãã«ã¯é©ç¨ãããªãããã§ãããã³ã³ã¹ãã©ã¯ã¿ã¼ããªãã¡ã¬ã³ã¹ä¿®é£¾ãããã¨ã¯ã§ããªãã
struct X {
virtual X() ; // ã¨ã©ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã«virtualæå®åã¯ä½¿ããªã
static X() ; // ã¨ã©ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã«staticæå®åã¯ä½¿ããªã
X() const ; // ã¨ã©ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯CV修飾ã§ããªã
X() & ; // ã¨ã©ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ãªãã¡ã¬ã³ã¹ä¿®é£¾ã§ããªã
} ;
ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼
å®å¼æ°ãªãã§å¼ã¹ãã³ã³ã¹ãã©ã¯ã¿ã¼ããããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ï¼default constructorï¼ã¨ãããããã«ã¯ãä»®å¼æ°ãåããªãã³ã³ã¹ãã©ã¯ã¿ã¼ã®ä»ã«ãä»®å¼æ°ã«ãã¹ã¦ããã©ã«ãå®å¼æ°ãæå®ããã¦ããã³ã³ã¹ãã©ã¯ã¿ã¼ãå«ã¾ããã
以ä¸ã¯ãã¹ã¦ãXã«å¯¾ããããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã®å®£è¨ã§ããã
X() ;
X( int = 0 ) ;
X( int = 0, int = 0 ) ;
ãããã¦ã¼ã¶ã¼å®ç¾©ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ãåå¨ããªãå ´åãæé»ã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ããããã©ã«ãåããã¦å®£è¨ãããã
struct X
{
// ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã®å®ç¾©ãªã
// æé»ã«ãX() = default ; ã宣è¨ããã
} ;
struct Y
{
Y(int) ; // ã¦ã¼ã¶ã¼å®ç¾©ã®ã³ã³ã¹ãã©ã¯ã¿ã¼
// æé»ã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯defaultåãããªã
} ;
ãã ãã以ä¸ã®ããããã®æ¡ä»¶ãã¿ããã¯ã©ã¹ã®å ´åãæé»ã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯deleteå®ç¾©ãããã
unionã®ãããªã¯ã©ã¹ã§ãå
±ç¨ã¡ã³ãã¼ãéããªãã¢ã«ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãæã¤å ´å
// éããªãã¢ã«ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãæã¤ã¯ã©ã¹
struct NonTrivial
{
NonTrivial() { } // éããªãã¢ã«ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼
} ;
// éããªãã¢ã«ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãæã¤ã¡ã³ãã¼ã®ããunion
union X
{
// æé»ã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯deleteå®ç¾©ããã
NonTrivial nt ;
} ;
// ãã®ãããªç¡åunionãç´æ¥ã®ã¡ã³ãã¼ã«æã¤ã¯ã©ã¹
struct Y
{
// æé»ã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯deleteå®ç¾©ããã
union { NonTrivial nt ; } ;
} ;
åæååã®ãªããªãã¡ã¬ã³ã¹åã®éstaticãã¼ã¿ã¡ã³ãã¼ãæã¤ã¯ã©ã¹ã®å ´å
int OBJECT ; // ã°ãã¼ãã«å¤æ°
struct X
{
// åæååã®ãªããªãã¡ã¬ã³ã¹åã®éstaticãã¼ã¿ã¡ã³ãã¼
int & ref ;
} ;
struct Y
{
// åæååããã
int & ref = OBJECT ;
} ;
struct Z
{
int & ref ;
// ã¦ã¼ã¶ã¼å®ç¾©ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ããã
Z() : ref( OBJECT ) { }
} ;
int main()
{
X x ; // ã¨ã©ã¼ãããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãdeleteå®ç¾©ããã
Y y ; // OK
Z z ; // OK
}
ã¯ã©ã¹Xã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯æé»ã«deleteå®ç¾©ããããY::refã«ã¯åæååããããZã«ã¯ã¦ã¼ã¶ã¼å®ç¾©ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ãããã
unionã®ã¡ã³ãã¼ã§ã¯ãªããconst修飾ãããåããããã¯ãã®é
ååã®ãéstaticãã¼ã¿ã¡ã³ãã¼ããã¦ã¼ã¶ã¼å®ç¾©ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãæãããåæååããªãå ´åã
// ã¦ã¼ã¶ã¼å®ç¾©ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãæããªãã¯ã©ã¹
struct NoUserDefined { } ;
struct X
{
// åæååããªã
NoUserDefined const member ;
NoUserDefined const array[1] ;
} ;
struct Y
{
// åæååããã
NoUserDefined const member = NoUserDefined() ;
} ;
struct Z
{
NoUserDefined const member ;
// memberã«å¯¾ããåæååããªãã®ã§ä¸å¯
// Z() : member() { } ãªãå¯
Z() { }
} ;
int main()
{
X x ; // ã¨ã©ã¼
Y y ; // OK
Z z ; // ã¨ã©ã¼
}
æ°ãã¤ããç¹ã¨ãã¦ã¯ãZã®ã¦ã¼ã¶ã¼å®ç¾©ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ããZ(){}ã¨ããå½¢ã®å ´åãZ::memberã«å¯¾ããåæååããªãã®ã§ãã¨ã©ã¼ã«ãªããZ() : member() { }ã¨ããå½¢ã®å ´åã¯ãåæååãããã®ã§ãã¨ã©ã¼ã«ã¯ãªããªãã
unionã®ãããªã¯ã©ã¹ã§ãå
±ç¨ã¡ã³ãã¼ãconst修飾ããã¦ããå ´åãããã«ã¯ãconst修飾ããã¦ããåã¸ã®é
ååãå«ãã
union X
{ // ãã¹ã¦const修飾ããã¦ãã
int const a ;
int const b ;
int const c[1] ;
} ;
struct Y
{ // ãã¹ã¦const修飾ããã¦ããç¡åunionãã¡ã³ãã¼ã«æã¤
X x ;
} ;
union Z
{
int a ; // const修飾ããã¦ããªã
int const b ;
int const c[1] ;
} ;
int main()
{
X x ; // ã¨ã©ã¼
Y y ; // ã¨ã©ã¼
Z z ; // OKãY::aã¯const修飾ããã¦ããªãã
}
unionã®ãã¹ã¦ã®éstaticãã¼ã¿ã¡ã³ãã¼ãconst修飾ããã¦ããå ´åã®ã¿ãããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãæé»ã«deleteå®ç¾©ããããã²ã¨ã¤ã§ãconst修飾ããã¦ããªãéstaticãã¼ã¿ã¡ã³ãã¼ãããå ´åããã®æ¡ä»¶ã«ã¯å½ã¦ã¯ã¾ããªãã
ç´æ¥ã®åºæ¬ã¯ã©ã¹ãä»®æ³åºæ¬ã¯ã©ã¹ãåæååã®ãªãéstaticãã¼ã¿ã¡ã³ãã¼ã®åããããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã使ããªãåã§ããå ´åãããã«ã¯ãé
ååãå«ã¾ããã
// ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã使ããªãã¯ã©ã¹ã®ä¾
struct X
{
X() = delete ;
} ;
// ç´æ¥ã®åºæ¬ã¯ã©ã¹
struct A : X { } ;
// ä»®æ³åºæ¬ã¯ã©ã¹
struct B : virtual X { } ;
// åæååã®ãªãéstaticãã¼ã¿ã¡ã³ãã¼
struct C
{
X a ;
X b[1] ;
} ;
ã¯ã©ã¹AãBãCã¯ãããããããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãæé»ã«deleteå®ç¾©ãããã
ããåã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã使ããªãå ´åã¨ããã®ã¯ã以ä¸ã®éãã§ããã
ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ããªãå ´åã
// ã¦ã¼ã¶ã¼å®ç¾©ã³ã³ã¹ãã©ã¯ã¿ã¼ãããå ´åãæé»ã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯å®ç¾©ãããªãã
struct NoDefaultConstructor { NoDefaultConstructor(int) ; } ;
struct X : NoDefaultConstructor { } ;
ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã®ãªã¼ãã¼ãã¼ã解決ã®çµæãææ§ã«ãªãå ´åã
struct Ambiguous
{
Ambiguous( int = 0 ) { }
Ambiguous( double = 0.0 ) { }
} ;
struct X : Ambiguous { } ;
int main()
{
Ambiguous a ; // ã¨ã©ã¼ãããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã®ãªã¼ãã¼ãã¼ã解決ãææ§
X b ; // ã¨ã©ã¼ãããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯æé»ã«deleteå®ç¾©ããã¦ãã
}
ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãdeleteå®ç¾©ããã¦ããå ´å
struct X
{
X() = delete ; // ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã®deleteå®ç¾©
} ;
ã¯ã©ã¹ã®ããã©ã«ãåãããããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãããããåã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã«ã¢ã¯ã»ã¹åºæ¥ãªãå ´åã
class B1
{
private :
B1() = default ;
} ;
class B2
{
private :
B2() { }
} ;
class D1 : public B1 { } ;
class D2 : public B2 { } ;
int main()
{
D1 a ; // ã¨ã©ã¼ãããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯æé»ã«deleteå®ç¾©ããã¦ãã
D2 b ; // ã¨ã©ã¼ãããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯æé»ã«deleteå®ç¾©ããã¦ãã
}
ã¯ã©ã¹B1ãB2ã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ãprivateã¡ã³ãã¼ãªã®ã§ãfriendã§ã¯ãªãã¯ã©ã¹D1ãD2ããã¯ã¢ã¯ã»ã¹ã§ããªãããã®ãããããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯æé»ã«deleteå®ç¾©ãããã
ãããã®æ¡ä»¶ã«å½ã¦ã¯ã¾ããªãå ´åãããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯æé»ã«defaultåãããã
ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãããªãã¢ã«ï¼trivialï¼ã¨ãªãããã«ã¯ã以ä¸ã®æ¡ä»¶ããã¹ã¦æºãããªããã°ãªããªãã
ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãã¦ã¼ã¶ã¼å®ç¾©ãdeleteå®ç¾©ãããã¦ããªããã¯ã©ã¹ã¯virtualé¢æ°ã¨virtualåºæ¬ã¯ã©ã¹ãæããªããã¯ã©ã¹ã®éstaticãã¼ã¿ã¡ã³ãã¼ã¯ãåæååãæããªããã¯ã©ã¹ã®ç´æ¥ã®åºæ¬ã¯ã©ã¹ã¯ãããªãã¢ã«ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãæã¤ãã¯ã©ã¹ã®éstaticãã¼ã¿ã¡ã³ãã¼ã¯ãããªãã¢ã«ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãæã¤ã
ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ã使ãããã¨ãã«ãæé»ã«defaultåããããããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãdeleteå®ç¾©ãããã«ãdefaultåãããå ´åãæé»ã«å®ç¾©ãããããã®æé»ã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ãã³ã³ã¹ãã©ã¯ã¿ã¼åæååãæ¸ããã³ã³ã¹ãã©ã¯ã¿ã¼ã®æ¬ä½ã空ã«ãããã¦ã¼ã¶ã¼å®ç¾©ã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¨åçã§ããã
struct X
{
// æé»ã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ã以ä¸ã®ã³ã¼ãã¨åã
// X(){}
} ;
struct Y { } ;
int main()
{
X x ; // æé»ã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã使ã
}
ã¯ã©ã¹Xã¯ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã使ããã¦ããã®ã§ãæé»ã«defaultåããããã¯ã©ã¹Yã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ä½¿ããã¦ããªãã®ã§ãå®ç¾©ãããªãã
ãããæé»ã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãå®ç¾©ããã¦ãã¦ãåçã®ã¦ã¼ã¶ã¼å®ç¾©ã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãæ¸ããå ´åã«ã¨ã©ã¼ã¨ãªãå ´åã¯ãããã°ã©ã ãã¨ã©ã¼ã¨ãªãã
struct X { int & ref ; } ;
struct Y { int & ref ; } ;
int main()
{
X x ; // ã¨ã©ã¼
int obj = 0 ;
Y y = { obj } ; // OK
}
ã¯ã©ã¹Xã¯ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã使ã£ã¦ããã®ã§ãæé»ã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãdefaultåãããããããããªãã¡ã¬ã³ã¹ã®éstaticãã¼ã¿ã¡ã³ãã¼ãæã¤ãã¨ã«ãããåçã®ã¦ã¼ã¶ã¼å®ç¾©ã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãã¨ã©ã¼ã«ãªãã®ã§ãã¨ã©ã¼ã¨ãªããä¸æ¹ãã¯ã©ã¹Yã§ã¯ãããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã使ããã¦ããªãã
åçã®ã¦ã¼ã¶ã¼å®ç¾©ã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãconstexprã³ã³ã¹ãã©ã¯ã¿ã¼ã®è¦æ±ãæºããå ´åãæé»ã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ããconstexprã³ã³ã¹ãã©ã¯ã¿ã¼ã«ãªãã
ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ãåæååãªãã§å®ç¾©ããããªãã¸ã§ã¯ãããé¢æ°å½¢å¼ã®æ示çãªãã£ã¹ãã«å¯¾ãã¦å¼ã°ããã
struct X { X() { } } ;
X x ; // ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãå¼ã°ãã
int main()
{
X x ; // ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãå¼ã°ãã
new X ; // ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãå¼ã°ãã
X() ; // ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãå¼ã°ãã
}
ã¯ã©ã¹ã®ãªãã¸ã§ã¯ããã³ãã¼ãã ã¼ãããéã«ã¯ãã³ãã¼ãã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ããããã使ãããã詳ããã¯ãã¯ã©ã¹ãªãã¸ã§ã¯ãã®ã³ãã¼ã¨ã ã¼ããåç
§ã
åºæ¬ã¯ã©ã¹ã¨éstaticãã¼ã¿ã¡ã³ãã¼ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ãå¼ã°ããé çªããå®å¼æ°ã®æ¸¡ãæ¹ã«ã¤ãã¦ã¯ãåºæ¬ã¯ã©ã¹ã¨ãã¼ã¿ã¡ã³ãã¼ã®åæåãåç
§ã
ãã®ä»ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã«ã¤ãã¦ã¯ãåå¤æã³ã³ã¹ãã©ã¯ã¿ã¼ãåç
§ã
ã³ã³ã¹ãã©ã¯ã¿ã¼ã«æ»ãå¤ã®åãæå®ãããã¨ã¯ã§ããªããã³ã³ã¹ãã©ã¯ã¿ã¼ã®æ¬ä½ã®ä¸ã§returnæã使ãå ´åã¯ãå¤ãæå®ãã¦ã¯ãªããªããã³ã³ã¹ãã©ã¯ã¿ã¼ã®ã¢ãã¬ã¹ãåå¾ãããã¨ã¯ã§ããªãã
constãªãªãã¸ã§ã¯ãã®æ§ç¯ä¸ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã®thisããç´æ¥ãéæ¥çã«çµç±ããªãglvalueã«ãã£ã¦ãªãã¸ã§ã¯ããã¾ãã¯ãã®ãµããªãã¸ã§ã¯ãã«ã¢ã¯ã»ã¹ããå ´åãå¤ã¯æªè¦å®ã§ããããã®å¶éã«ã¯ãé常ãã¾ãééãããã¨ã¯ãªããä¾ãã°ã以ä¸ã®ãããªã³ã¼ããåé¡ã«ãªãã
struct C ;
void f( C * ) ;
struct C
{
int value ;
C() : c(123)
{ // ãªãã¸ã§ã¯ãã¯ãã¾ã æ§ç¯ä¸
f( this ) ; // ãªãã¸ã§ã¯ãã®æ§ç¯ä¸ã«å¼ã³åºã
}
} ;
const C cobj ; // staticã¹ãã¬ã¼ã¸ä¸ã®constãªãªãã¸ã§ã¯ã
void f( C* cptr )
{
cptr->value ; // OKãå¤ã¯123ãcptrã¯ã³ã³ã¹ãã©ã¯ã¿ã¼ã®thisç±æ¥
cobj.value ; // å¤ã¯æªè¦å®
}
ãªãã¸ã§ã¯ãã¯ãã³ã³ã¹ãã©ã¯ã¿ã¼ãå®è¡ãçµãã£ãæç¹ã§ãæ§ç¯æ¸ã¿ã¨ãªããã³ã³ã¹ãã©ã¯ã¿ã¼ãå®è¡ä¸ã¨ãããã¨ã¯ãã¾ã ãªãã¸ã§ã¯ãã¯æ§ç¯ä¸ã¨ãããã¨ã§ãããcobjã¯ãããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãå¼ã³åºãããããã£ã¦ãé¢æ°fã¯ãcobjã®æ§ç¯ä¸ã«å¼ã³åºãããã¨ãããã¨ã«ãªããcptrã®å¤ã¯ãã³ã³ã¹ãã©ã¯ã¿ã¼ã®thisã«ãã£ã¦å¾ãããã¢ãã¬ã¹ã§ããããããã£ã¦ãcptrã®å¤ã§ãããCã®ãªãã¸ã§ã¯ãã¸ã®ã¢ãã¬ã¹ãåç
§ãã¦ãcobjã«ã¢ã¯ã»ã¹ãããã¨ã¯ã§ãããé¢æ°fã¯ãã¯ã©ã¹Cã®ã³ã³ã¹ãã©ã¯ã¿ã¼ããå¼ã³åºããã¦ãããé¢æ°fã®ä¸ããcobjãç´æ¥åç
§ããã¨ãããã¨ã¯ãcobjã®æ§ç¯ä¸ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã®thisã«ãããã«ã¢ã¯ã»ã¹ããã¨ãããã¨ã§ããããã®å ´åãå¤ã¯æªè¦å®ã¨ãªãããã®ä¾ã§ã¯ã123ã§ããã¨ã¯ä¿è¨¼ãããªãã
ãã®æ¡ä»¶ã«å½ã¦ã¯ã¾ããããªã³ã¼ãã¯ãç¾å®ã«ã¯æ¥µãã¦çããã
ä¸æãªãã¸ã§ã¯ãï¼temporary objectï¼ã¯ãæ§ã
ãªå ´é¢ã§ãèªåçã«çæãç ´æ£ããããä¾ãã°ãprvalueããªãã¡ã¬ã³ã¹ã«æç¸ãããprvalueãè¿ããprvalueãçæããåå¤æãä¾å¤ã®throwããã³ãã©ã¼ã§ãã£ãããåæåãªã©ã§ãããä¾å¤ã«ãããä¸æãªãã¸ã§ã¯ãã®å¯¿å½ã¯ãä¾å¤ãåç
§ã
struct X { } ;
X f()
{
return X() ; // prvalueãçæããåå¤æ
}
int main()
{
int && ref = 0 ; // prvalueããªãã¡ã¬ã³ã¹ã«æç¸ãã
f() ; // prvalueãè¿ã
}
å®è£
ã¯ä¸æãªãã¸ã§ã¯ãã®çæãçç¥ã§ãããä¾ãã°ã以ä¸ã®ã³ã¼ãã«ã¤ãã¦èããã
struct X
{
X( int ) ; // ã³ã³ã¹ãã©ã¯ã¿ã¼
X( X const & ) ; // ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼
X & operator = ( X const & ) ; // ã³ãã¼ä»£å
¥æ¼ç®å
~X() ; // ãã¹ãã©ã¯ã¿ã¼
} ;
struct Y
{
Y( int ) ; // ã³ã³ã¹ãã©ã¯ã¿ã¼
Y( Y && ) ; // ã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼
~Y() ; // ãã¹ãã©ã¯ã¿ã¼
};
X f( X ) ;
Y g( Y ) ;
int main()
{
X a = f( X(2) ) ; // #1
Y b = g( Y(3) ) ; // #2
X c(1) ;
c = f(c) ; // #3
}
#1ã«ã¤ãã¦èãããããå®è£
ã§ã¯ãX(2)ã¨ããå¼ã§ä¸æãªãã¸ã§ã¯ããã²ã¨ã¤ä½ãããé¢æ°ã®å®å¼æ°ã¨ãã¦æ¸¡ãéã«ãå¥ã®ä¸æãªãã¸ã§ã¯ããã²ã¨ã¤ä½ããã¦ã³ãã¼ããããããããªããé¢æ°ã®æ»ãå¤ããå¥ã®ä¸æãªãã¸ã§ã¯ããã²ã¨ã¤ä½ããã¦ãå¤æ°aã«ã³ãã¼ããããããããªããå¥ã®å®è£
ã§ã¯ãX(2)ã¨ããå¼ã«ããä¸æãªãã¸ã§ã¯ãã¯ãé¢æ°ã®å®å¼æ°ã®ä¸æãªãã¸ã§ã¯ãä¸ã«ç´æ¥æ§ç¯ãããã®ã§ãä¸æãªãã¸ã§ã¯ããçç¥ã§ãããããããªããé¢æ°ã®æ»ãå¤ããå¤æ°aã®ãªãã¸ã§ã¯ãä¸ã«ç´æ¥æ§ç¯ãããã®ã§ãä¸æãªãã¸ã§ã¯ããçç¥ã§ãããããããªãã
#2ããã³ãã¼ãã ã¼ãã«ãå¤æ°aãbã«å¤ãã£ãã ãã§ãåããã¨ãè¨ããã
#3ã§ã¯ãå¤æ°cã¯ããã§ã«æ§ç¯ããããªãã¸ã§ã¯ããªã®ã§ãé¢æ°ã®æ»ãå¤ã®ä¸æãªãã¸ã§ã¯ãããå¤æ°cã®ãªãã¸ã§ã¯ãã®ä¸ã«ãç´æ¥æ§ç¯ãããã¨ã¯ã§ããªããããã§ã¯ä¸æãªãã¸ã§ã¯ããæ§ç¯ãããå¤æ°cã«ã³ãã¼ãããã
ä¸æãªãã¸ã§ã¯ãã®æ§ç¯ãçç¥ãããã¨ãã¦ããããä¸æãªãã¸ã§ã¯ããä½æãã¦ããã°ã¨ã©ã¼ã«ãªããããªã³ã¼ãã¯ãã¨ã©ã¼ã«ãªãããã¨ãã°ãã³ã³ã¹ãã©ã¯ã¿ã¼ããã¹ãã©ã¯ã¿ã¼ã«ã¢ã¯ã»ã¹ã§ããªãå ´åã ã
ä¸è¬ã«ãããå¼ã«ããã¦ä¸æãªãã¸ã§ã¯ããããã¤æ§ç¯ããããã¨ãããã¨ã¯ãè¦æ ¼ã§ã¯å®ç¾©ããã¦ããªããå®è£
次第ã§ãããä¸æãªãã¸ã§ã¯ããæ§ç¯ãããªããã°ãã³ã³ã¹ãã©ã¯ã¿ã¼ããã¹ãã©ã¯ã¿ã¼ãå¼ã°ããªãã
éã«ãä¸æãªãã¸ã§ã¯ããæ§ç¯ãããå ´åãéããªãã¢ã«ãªã³ã³ã¹ãã©ã¯ã¿ã¼ã¯å¿
ãå¼ã³åºãããããç ´æ£ããã¨ãã«ã¯ãéããªãã¢ã«ãªãã¹ãã©ã¯ã¿ã¼ã¯å¿
ãå¼ã³åºãããã
ä¸æãªãã¸ã§ã¯ãã®ç ´æ£ã¯ååã¨ãã¦ããã®ä¸æãªãã¸ã§ã¯ããæ§ç¯ãããã¨ã«ãªã£ãå¼ãå«ãå®å
¨å¼ã®è©ä¾¡ã®æå¾ã®æ®µéã¨ãã¦ãå®è¡ããããè¨ããããã°ãä¸æãªãã¸ã§ã¯ãã®å¯¿å½ã¯ãå®å
¨å¼ãè©ä¾¡ããçµããã¾ã§ã¨ãããã¨ãã§ããã
struct X
{
X operator + ( X const & ){ return X() ; }
} ;
int main()
{
X a = 0 ;
X b = a + a + a ;
}
ãã®ä¾ã§ãbã®åæååã®ä¸ã®å¼ã«ããã¦æ§ç¯ãããä¸æãªãã¸ã§ã¯ããããããã°ããã®å¯¿å½ã¯ãã½ã¼ã¹ã³ã¼ãä¸ã§è¨ãã°ãã»ãã³ãã³ã¾ã§ã¨ãªãã
ãã ãããã®ååã«å¾ããªãå ´åãããµãã¤åå¨ããã
ã²ã¨ã¤ã¯ãé
åã®è¦ç´ ãåæåããéã«ãããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãããã©ã«ãå®å¼æ°ãæã£ã¦ããå ´åãããè¦ç´ ã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼å®è¡ã«ãããä¸æãªãã¸ã§ã¯ãã®ç ´æ£ã¯ã次ã®è¦ç´ ã®åæåã®åã«è¡ããããç ´æ£ã«ä¼´ããããããµã¤ãã¨ãã§ã¯ãã¯ã次ã®è¦ç´ ã®åæåã®ä»¥åã«ã·ã¼ã±ã³ã¹ï¼sequenced beforeï¼ãããã
struct Fat { char [1000] ; } ;
struct X
{
X( Fat f = Fat() ) { } // ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼
} ;
int main()
{
X a[1000] ;
}
ãã®ä¾ã§ã¯ãa[0]ããa[999]ã¾ã§ã®1000åã®Xåã®é
åã®è¦ç´ ã«å¯¾ããããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãå¼ã³åºãããããããa[0]ãa[1]ã®åã«åæåãããå ´åãa[0]ã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼å¼ã³åºãã«ãã£ã¦æ§ç¯ãããFatåã®ä¸æãªãã¸ã§ã¯ãã¯ãa[1]ãåæåããã¨ãã«ã¯ããã§ã«ç ´æ£ããã¦ãããé
åã®ãã¹ã¦ã®è¦ç´ ãåæåãçµããã¾ã§ã1000åã®Fatåã®ä¸æãªãã¸ã§ã¯ããä¿æããããã¨ã¯ãªãã
ããã²ã¨ã¤ã¯ãä¸æãªãã¸ã§ã¯ãããªãã¡ã¬ã³ã¹ã«æç¸ããå ´åãä¸æãªãã¸ã§ã¯ãã®å¯¿å½ã¯ããªãã¡ã¬ã³ã¹ã®å¯¿å½ã¾ã§å»¶é·ããããä¸æãªãã¸ã§ã¯ãã¯ãrvalueãªãã¡ã¬ã³ã¹ããconstãªlvalueãªãã¡ã¬ã³ã¹ã§æç¸ã§ããã
struct X { } ;
int main()
{
{
X const & lvalue_reference = X() ;
X && rvalue_reference = X() ;
// ä¸æãªãã¸ã§ã¯ãã®å¯¿å½ã¯ããã¾ã§
}
}
ãã ãããã®ãªãã¡ã¬ã³ã¹æç¸ã®å¯¿å½ã®å»¶é·ã«ã¯ãããã¤ãã®ä¾å¤ãåå¨ããã
ã³ã³ã¹ãã©ã¯ã¿ã¼åæååã«ãã£ã¦ãªãã¡ã¬ã³ã¹ã®ã¡ã³ãã¼ã«æç¸ãããä¸æãªãã¸ã§ã¯ãã®å¯¿å½ã¯ãã³ã³ã¹ãã©ã¯ã¿ã¼å¼ã³åºããçµäºããã¾ã§ã§ããã
struct Member { } ;
struct X
{
Member const & ref ;
X( Member const & ref ) : ref(ref)
{
// refã¯å¦¥å½ãªãªãã¸ã§ã¯ããåç
§ãã¦ãã
}
} ;
int main()
{
X x = Member() ;
// ä¸æãªãã¸ã§ã¯ããç ´æ£ããã
// x.refã¯ç¡å¹ãªãªãã¸ã§ã¯ããåç
§ãã¦ãã
}
ãããã¯ã©ã¹Xã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã®å®å¼æ°ããä¸æãªãã¸ã§ã¯ãã¸ã®ãªãã¡ã¬ã³ã¹ã ã£ãå ´åãä¸æãªãã¸ã§ã¯ãã®å¯¿å½ã¯ãã³ã³ã¹ãã©ã¯ã¿ã¼å¼ã³åºããçµäºããã¾ã§ã§ããããã®ãããåæåã®çµãã£ãå¤æ°xã®ã¡ã³ãã¼refã¯ãç¡å¹ãªãªãã¸ã§ã¯ããåç
§ãã¦ãããã¨ã«ãªãã
ä»®å¼æ°ã®ãªãã¡ã¬ã³ã¹ã«æç¸ãããä¸æãªãã¸ã§ã¯ãã®å¯¿å½ã¯ãé¢æ°å¼ã³åºããå«ãå¼ã®å®å
¨å¼ã®è©ä¾¡ãçµäºããã¾ã§ã§ããã
struct X { } ;
void f( X const & ref )
{
// refã¯å¦¥å½ãªãªãã¸ã§ã¯ããåç
§ãã¦ãã
}
int main()
{
f( X() ) ;
// ä¸æãªãã¸ã§ã¯ããç ´æ£ããã
}
ãã®ä¾ã§ãX()ãå«ãå®å
¨å¼ã¨ããã®ã¯ãé¢æ°fã«å¯¾ããé¢æ°å¼ã³åºãå¼ã®ãªãã©ã³ãã§ããããããã£ã¦ãå®å
¨å¼ã¯X()ã¨ãªãããããããã®è§£éã«å¾ãã¨ãé¢æ°ã®æ¬ä½ã§ã¯ãrefã¯ç¡å¹ãªãªãã¸ã§ã¯ããåç
§ãããã¨ã«ãªã£ã¦ãã¾ãããã®ãããä»®å¼æ°ã®ãªãã¡ã¬ã³ã¹æç¸ã«å¯¾ãã¦ã¯ãé¢æ°å¼ã³åºããå«ãå®å
¨å¼ã«ãªãããã®å ´åãf( X() )ã§ããããã®ãããX()ã«ãã£ã¦æ§ç¯ãããä¸æãªãã¸ã§ã¯ãã¯ãé¢æ°fã®æ¬ä½ã®ä¸ã§ã妥å½ã§ããã
é¢æ°ã®returnæã«ãã£ã¦æ§ç¯ããããé¢æ°ã®æ»ãå¤ã®ãªãã¡ã¬ã³ã¹ã«æç¸ãããä¸æãªãã¸ã§ã¯ãã®å¯¿å½ã¯ã延é·ãããªããä¸æãªãã¸ã§ã¯ãã¯ãreturnæãå«ãå®å
¨å¼ã®çµäºããã£ã¦ãç ´æ£ãããã
struct X { } ;
X const & f( X const & ref )
{
return X() ;
}
int main()
{
X const & ref = f( X() ) ;
// ä¸æãªãã¸ã§ã¯ãã¯ç ´æ£ããã
// refã¯ç¡å¹ãªãªãã¸ã§ã¯ããåç
§ãã¦ãã
}
ãã®ããã«ãé¢æ°ã®æ»ãå¤ã¨ãã¦ã®ãªãã¡ã¬ã³ã¹ã«æç¸ããã¦ããä¸æãªãã¸ã§ã¯ãã®å¯¿å½ã¯å»¶é·ãããªããããã«ã¯æ³¨æãå¿
è¦ã§ããã
newåæååã®ä¸ã§ãªãã¡ã¬ã³ã¹æç¸ãããä¸æãªãã¸ã§ã¯ãã®å¯¿å½ã¯ãnewåæååãå«ãå®å
¨å¼ã®çµããã¾ã§ã§ããã
struct X { int const & ref ; } ;
int main()
{
X * ptr = new X{ 0 } ;
// ä¸æãªãã¸ã§ã¯ããç ´æ£ããã
// ptr->refã¯ç¡å¹ãªãªãã¸ã§ã¯ããåç
§ãã¦ãã
}
ãªãã¡ã¬ã³ã¹æç¸ã«ããã寿å½ã®å»¶é·ãåãã¦ããªãä¸æãªãã¸ã§ã¯ãã®ç ´æ£ã®é çªã¯ãæ§ç¯ã®éé ã«è¡ããããå¾ã«æ§ç¯ãããä¸æãªãã¸ã§ã¯ãã®æ¹ããå
ã«æ§ç¯ãããä¸æãªãã¸ã§ã¯ããããå
ã«ç ´æ£ãããã
ããããªãã¡ã¬ã³ã¹æç¸ãåãããè¤æ°ã®ä¸æãªãã¸ã§ã¯ãããåãå ´æã§ç ´æ£ãããå ´åãç ´æ£ã®é çªã¯ãæ§ç¯ã®éé ã«è¡ãããã
struct X { X( int ) { } } ;
void f( X const &, X const & ) { }
int main()
{
f( X(1), X(2) ) ; // #1
}
ä»ã#1ã®X(1)ãX(2)ã¨ããå¼ã«å¯¾ãã¦ãããããä¸æãªãã¸ã§ã¯ããæ§ç¯ãããã¨ãããé¢æ°ã®å®å¼æ°ã®è©ä¾¡é åºã¯è¦å®ããã¦ããªãã®ã§ãã©ã¡ããå
ã«æ§ç¯ããããã¯ãè¦æ ¼ã®å®ããã¨ããã§ã¯ãªããããããä»®ã«X(1)ã®ä¸æãªãã¸ã§ã¯ãããX(2)ã«å
ããã¦æ§ç¯ãããå ´åããªãã¸ã§ã¯ãã®ç ´æ£ã¯ãX(2)ãå
ã«ãªãã
ã¯ã©ã¹ã®åå¤æãå®ç¾ããã«ã¯ãæ¹æ³ããµãã¤ãããã³ã³ã¹ãã©ã¯ã¿ã¼ã¨å¤æé¢æ°ï¼conversion functionï¼ã ããã®ãµãã¤ãåããã¦ãã¦ã¼ã¶ã¼å®ç¾©åå¤æï¼user-deï¬ned conversionsï¼ã¨ãããã¦ã¼ã¶ã¼å®ç¾©åå¤æã¯ãæé»ã®åå¤æãåæåãæ示çãªåå¤æã«ç¨ããããã
ã²ã¨ã¤ã®å¤ã«å¯¾ãã¦ãã¦ã¼ã¶ã¼å®ç¾©åå¤æã¯1åããé©ç¨ãããªãã
struct X { } ;
struct Y
{
Y( int ){ } // intåããYåã¸
operator X() { return X() ; } // YåããXåã¸
} ;
int main()
{
Y a = 0 ; // OKãintåããYåã¸ã®åå¤æ
X b = Y(0) ; // OKãYåããXåã¸ã®åå¤æ
X c = 0 ; // ã¨ã©ã¼
}
ã¦ã¼ã¶ã¼å®ç¾©åå¤æã«ãã£ã¦ãintåããYåã«å¤æãããã¨ã¯ã§ãããã¾ããYåããXåã«å¤æãããã¨ã¯ã§ããããã ããintåãããæé»ã«Xåã«å¤æãããã¨ã¯ã§ããªãããªããªãã°ãããã«ã¯ã¦ã¼ã¶ã¼å®ç¾©åå¤æãã2åé©ç¨ããªããã°ãªããªãããã ã
ã¦ã¼ã¶ã¼å®ç¾©åå¤æã¯ãææ§ã«ãªããªãå ´åã®ã¿ãæé»ã«ä½¿ããããæ´¾çã¯ã©ã¹ã®åå¤æé¢æ°ã¯ãåºæ¬ã¯ã©ã¹ã®åå¤æé¢æ°ãé ããªãããã ããåãåã«å¯¾ããåå¤æé¢æ°ã®å ´åãé¤ããè¤æ°ã®åå¤æé¢æ°ãããå ´åãé¢æ°ã®ãªã¼ãã¼ãã¼ã解決ã¨åãæ¹æ³ã§ãæé©ãªé¢æ°ã解決ãããã
struct Base
{
operator int() { return 0 ; }
} ;
struct Derived : Base
{
// Base::operator intãé ããªã
operator char() { return char(0) ; }
} ;
int main()
{
Derived obj ;
int a = obj ; // OK
char b = obj ; // OK
bool c = obj ; // ã¨ã©ã¼ãææ§
}
explicitæå®åã使ããã«å®£è¨ããã¦ããã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ãä»®å¼æ°ããã¯ã©ã¹ã¸ã®åå¤æã®æ¹æ³ãæå®ããã¡ã³ãã¼é¢æ°ã§ããããã®ãããªé¢æ°ããåå¤æã³ã³ã¹ãã©ã¯ã¿ã¼ï¼converting constructorï¼ã¨ããã
struct X
{
X( int ) {} // intåããã®åå¤æãæä¾
X( double ) {} // doubleåããã®åå¤æãæä¾
X( int, int, int ) ; // 3åã®intåããã®åå¤æãæä¾
} ;
int main()
{
X a = 0 ; // intåããã®åå¤æ
X b(0) ; // intåããã®åå¤æ
X c = 0.0 ; // doubleåããã®åå¤æ
X d( 1, 2, 3 ) ;
}
åå¤æã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ãä»®å¼æ°ããã¯ã©ã¹åã¸ã®å¤ææ¹æ³ãæå®ãããä»®å¼æ°ã¯ãè¤æ°ã§ãããã
explicitæå®åã®ããã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ãexplicitã®ãªãã³ã³ã¹ãã©ã¯ã¿ã¼ã¨ã»ã¼åãã§ããããã ããexplicitã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ãç´æ¥åæåãããã£ã¹ããæ示çã«ä½¿ãããã¨ãã«ããã使ãããªãã
struct X
{
explicit X( int ) {} // explicitã³ã³ã¹ãã©ã¯ã¿ã¼
} ;
void f( X ) { }
int main()
{
X a = 0 ; // ã¨ã©ã¼
X b(0) ; // OKãç´æ¥åæå
X c = X(0) ; // OKãæ示çãªãã£ã¹ã
X d = static_cast<X>(0) ; // OKãæ示çãªãã£ã¹ã
f( 0 ) ; // ã¨ã©ã¼
f( static_cast<X>(0) ) ; // OK
}
ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ãã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã«ããexplicitãæå®ã§ããããããã®é¢æ°ããexplicitæå®åãæå®ããªãå ´åãæé»ã«ä½¿ãããã
struct X
{
X() { }
explicit X( X const & ) {} // explicitã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼
} ;
int main()
{
X a ;
X b = a ; // ã¨ã©ã¼ãã³ãã¼åæåï¼ä»£å
¥å¼ã¨ã¯éããã¨ã«æ³¨æï¼
X c( a ) ; // OKãç´æ¥åæå
}
ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã«å¯¾ããexplicitæå®åã®æç¡ã¯ã以ä¸ã®ã³ã¼ãä¾ã®ãããªéããããããã
struct X
{
X() { }
} ;
struct Y
{
explicit Y() { }
} ;
int main( )
{
X x( { } ) ; // OKãéexplicitããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼
Y y( { } ) ; // ã¨ã©ã¼ãexplicitããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼
}
å®ç¨ä¸ãæ°ã«ãªãã»ã©ã®éãã¯ãªãã
以ä¸ã®ãããªææ³ã§å®£è¨ãããã¡ã³ãã¼é¢æ°ããåå¤æé¢æ°ï¼Conversion functionï¼ã¨ããã
explicitopt operator åèå¥å ( )
åå¤æé¢æ°ã¯ãä»®å¼æ°ãåãããæ»ãå¤ã®åãæå®ããªããåå¤æé¢æ°ã¯ãã¡ã³ãã¼ã§ããã¯ã©ã¹åãããåèå¥åã®åã¸ã®åå¤æãæä¾ããã
struct X
{
operator int() { return 0 ; }
} ;
int main()
{
X x ;
int i = x ; // 0
}
ãã®ä¾ã§ã¯ãã¯ã©ã¹Xã¯ãæé»ã«intåã®0ã«å¤æã§ããã¯ã©ã¹ã¨ãªãã
åå¤æé¢æ°ã®åã¯ããä»®å¼æ°ãåãããåèå¥åã®åãè¿ããã¡ã³ãã¼é¢æ°ãã«ãªãã
struct X
{
operator int() const { return 0 ; }
} ;
int main()
{
// åã¯int (X::*)(void) const
int (X::*ptr)(void) const = &X::operator int ; // ãã¤ã³ã¿ã¼ãå¾ã
X x ;
(x.*ptr)() ; // å¼ã³åºã
}
åèå¥åããèªåèªèº«ã®ã¯ã©ã¹åï¼ãªãã¡ã¬ã³ã¹ãå«ãï¼ãèªåèªèº«ã®åºæ¬ã¯ã©ã¹åï¼ãªãã¡ã¬ã³ã¹ãå«ãï¼ãvoidåãã¾ããããã®åã«CV修飾åãä»ããåã®å ´åãåå¤æé¢æ°ã使ããããã¨ã¯ãªãããããã®åå¤æã«ã¯ãæ¨æºåå¤æãç¨ãããããåå¤æé¢æ°ã¯ä½¿ãããªãããããã®åå¤æé¢æ°ã宣è¨ãããã¨ã¯ã¨ã©ã¼ã§ã¯ãªããã使ããããã¨ã¯ãªãã
struct Base{ } ;
struct Derived : Base
{
// ãããã®åå¤æé¢æ°ã¯ã使ããããã¨ã¯ãªã
operator Derived () ; // èªåèªèº«ã®ã¯ã©ã¹å
operator Derived & () ; // èªåèªèº«ã®ã¯ã©ã¹ã¸ã®ãªãã¡ã¬ã³ã¹å
operator Derived const & () ; // èªåèªèº«ã®ã¯ã©ã¹ã¸ã®constãªãã¡ã¬ã³ã¹å
operator Base () ; // åºæ¬ã¯ã©ã¹å
operator void () ; // voidå
} ;
int main()
{
Derived d ;
Base b = d ; // æ¨æºåå¤æã使ããããåå¤æé¢æ°ã¯ä½¿ãããªã
}
åå¤æé¢æ°ã«explicitæå®åãæå®ããã¦ããå ´åãåå¤æé¢æ°ã¯ãç´æ¥åæåãæ示çãªãã£ã¹ãã使ãããªããã°ãå¼ã³åºãããªãã
struct A { } ;
struct B { } ;
struct X
{
operator A() { return A() ; }
explicit operator B() { return B() ; }
} ;
int main()
{
X x ;
A a1 = x ; // OK
A a2(x) ; // OK
A a3 = A(x) ; // OK
B b1 = x ; // ã¨ã©ã¼ãã³ãã¼åæå
B b2(x) ; // OKãç´æ¥åæå
B b3 = B(x) ; // OKãæ示çãªãã£ã¹ã
}
åå¤æé¢æ°ã®åèå¥åããé¢æ°åã¨é
ååã«ãããã¨ã¯ã§ããªãã
struct X
{
operator void (void) () ; // ã¨ã©ã¼ãé¢æ°å
operator int[1] () ; // ã¨ã©ã¼ãé
åå
} ;
ãã®ä»ã®åã«ã¯ãç¹ã«å¶éã¯ãªãã
struct Y { } ;
struct X
{
using pointer_type = void (*)(void) ;
using reference_type = int (&)[1] ;
operator pointer_type () ; // é¢æ°ãã¤ã³ã¿âå
operator reference_type () ; // é
åã¸ã®åç
§å
operator Y() ; // ä»ã®ã¯ã©ã¹å
} ;
åå¤æé¢æ°ã¯ç¶æ¿ãããã
struct Base
{
operator int() { return 0 ; }
} ;
struct Derived : Base { } ;
int main()
{
Derived d ;
int i = d ; // Base::operator intãå¼ã³åºã
}
åå¤æé¢æ°ã¯virtualé¢æ°ã«ã§ããã
struct Base
{
// ãã¥ã¢virtualé¢æ°
virtual operator int() = 0 ;
} ;
struct Derived : Base
{
// ãªã¼ãã¼ã©ã¤ã
virtual operator int() { return 0 ; }
} ;
åå¤æé¢æ°ã¯staticé¢æ°ã«ã¯ã§ããªãã
struct X
{
static operator int() ; // ã¨ã©ã¼
} ;
以ä¸ã®ãããªææ³ã®å®£è¨ãããã¹ãã©ã¯ã¿ã¼ï¼destructorï¼ã¨ããã
é¢æ°æå®åopt ~ ã¯ã©ã¹å ( )
ãã¹ãã©ã¯ã¿ã¼ã®å®£è¨ã¯ã~ï¼ãã«ãï¼ã«ç¶ãã¦ãã¯ã©ã¹åã空ã®å¼æ°ãªã¹ããæå®ãããé¢æ°æå®åã«ã¯ãinlineã¨virtualãæå®ã§ãããã¯ã©ã¹åã®ä»£ããã«ãtypedefåã使ç¨ãããã¨ã¯ã§ããªãã
struct X
{
~X() ; // ãã¹ãã©ã¯ã¿ã¼ã®å®£è¨
} ;
ãã¹ãã©ã¯ã¿ã¼ã¯ã¯ã©ã¹åã®ãªãã¸ã§ã¯ããç ´æ£ããéã«ä½¿ãããããã¹ãã©ã¯ã¿ã¼ã«ã¯ãä»®å¼æ°ãæ»ãå¤ã®åãæå®ãããã¨ã¯ã§ããªãããã¹ãã©ã¯ã¿ã¼ã®ã¢ãã¬ã¹ãå¾ããã¨ã¯ã§ããªãããã¹ãã©ã¯ã¿ã¼ã¯staticã¡ã³ãã¼ã«ã¯ãªããªãããã¹ãã©ã¯ã¿ã¼ã¯ãCV修飾ããªãã¡ã¬ã³ã¹ä¿®é£¾ã§ããªãããã ãããã¹ãã©ã¯ã¿ã¼ã¯ãCV修飾ãããã¯ã©ã¹åã®ãªãã¸ã§ã¯ãã«å¯¾ãã¦ãå¼ã³åºãããã
struct X
{
~X() { }
} ;
int main()
{
{
X x ;
// ãªãã¸ã§ã¯ãç ´æ£ããã¹ãã©ã¯ã¿ã¼ãå¼ã°ãã
}
X * ptr = new X ;
delete ptr ; // ãªãã¸ã§ã¯ãç ´æ£ããã¹ãã©ã¯ã¿ã¼ãå¼ã°ãã
}
ãã¹ãã©ã¯ã¿ã¼ã®å®£è¨ã«ä¾å¤æå®ããªãå ´åã¯ãæé»ã®ãã¹ãã©ã¯ã¿ã¼ã¨åçã®ä¾å¤æå®ããæé»ã«æå®ãããã詳ããã¯ãä¾å¤æå®ãåç
§ã
ã¯ã©ã¹ã«ã¦ã¼ã¶ã¼å®£è¨ããããã¹ãã©ã¯ã¿ã¼ããªãå ´åããã¹ãã©ã¯ã¿ã¼ã¯æé»ã«defaultåããã¦å®£è¨ããããæé»ã«å®£è¨ããããã¹ãã©ã¯ã¿ã¼ã¯ãã¯ã©ã¹ã®inline publicã¡ã³ãã¼ã§ããã
æé»ã®ãã¹ãã©ã¯ã¿ã¼ã¯ã以ä¸ã®ããããã®æ¡ä»¶ãæºãããã¨ããdeleteå®ç¾©ãããã
unionã®ãããªã¯ã©ã¹ã§ãå
±ç¨ã¡ã³ãã¼ããéããªãã¢ã«ãã¹ãã©ã¯ã¿ã¼ãæã¤å ´åã
struct Trivial { } ;
struct NonTrivial { ~NonTrivial() { } } ;
// ãã¹ãã©ã¯ã¿ã¼ã¯æé»ã«defaultåããã
union A1 { Trivial member ; } ;
struct A2 { union { Trivial member ; } ; } ;
// ãã¹ãã©ã¯ã¿ã¼ã¯æé»ã«deleteå®ç¾©ããã
union B1 { NonTrivial member ; } ;
struct B2 { union { NonTrivial member ; } ; } ;
int main()
{
// OKãæé»ã®ãã¹ãã©ã¯ã¿ã¼ã使ã
A1 a1 ; A2 a2 ;
// ã¨ã©ã¼ãæé»ã®ãã¹ãã©ã¯ã¿ã¼ã¯deleteå®ç¾©ããã¦ãã
B1 b1 ; B2 b2 ;
}
ã¯ã©ã¹ã®éstaticãã¼ã¿ã¡ã³ãã¼ã®ãã¹ãã©ã¯ã¿ã¼ãdeleteå®ç¾©ããã¦ããããããã©ã«ããã¹ãã©ã¯ã¿ã¼ããã¢ã¯ã»ã¹åºæ¥ãªãå ´åã
struct deleted_destructor
{
~deleted_destructor() = delete ;
} ;
struct inaccessible_destructor
{
private :
~inaccessible_destructor() ;
friend struct Y ;
} ;
// ã¯ã©ã¹ã®ãã¹ãã©ã¯ã¿ã¼ã¯æé»ã«deleteå®ç¾©ããã
struct X
{
deleted_destructor m1 ; // ãã¹ãã©ã¯ã¿ã¼ãdeleteå®ç¾©ããã¦ãã
inaccessible_destructor m2 ; // ãã¹ãã©ã¯ã¿ã¼ã«ã¢ã¯ã»ã¹åºæ¥ãªã
} ;
struct Y
{
inaccessible_destructor m ; // friendãªã®ã§ããã¹ãã©ã¯ã¿ã¼ã«ã¢ã¯ã»ã¹å¯è½
} ;
ç´æ¥ã®åºæ¬ã¯ã©ã¹ããããã¯ãvirtualåºæ¬ã¯ã©ã¹ã®ãã¹ãã©ã¯ã¿ã¼ãdeleteå®ç¾©ããã¦ããããããã©ã«ããã¹ãã©ã¯ã¿ã¼ããã¢ã¯ã»ã¹åºæ¥ãªãå ´åã
struct Base
{
~Base() = delete ;
} ;
struct D1 : Base
{
// D1ã®ãã¹ãã©ã¯ã¿ã¼ã¯deleteå®ç¾©ããã
} ;
éæ¥ã®åºæ¬ã¯ã©ã¹ã®ãã¹ãã©ã¯ã¿ã¼ã¯ãå½±é¿ããªãã
struct Base
{
private :
~Base() { }
friend struct D1 ;
} ;
struct D1 : Base
{
// friend宣è¨ã«ãããBaseã®ãã¹ãã©ã¯ã¿ã¼ã«ã¢ã¯ã»ã¹ã§ãã
} ;
struct D2 : D1
{
// D1ã®ãã¹ãã©ã¯ã¿ã¼ã«ã¢ã¯ã»ã¹ã§ãã
} ;
int main()
{
D1 d1 ; // OK
D2 d2 ; // OK
}
ãã ããvirtualåºæ¬ã¯ã©ã¹ã«ã¯ãç´æ¥ã¨éæ¥ã®éãã¯ãªãã®ã§ãå½±é¿ããã
struct Base
{
private :
~Base() { }
friend struct D1 ;
} ;
struct D1 : virtual Base
{
// friend宣è¨ã«ãããBaseã®ãã¹ãã©ã¯ã¿ã¼ã«ã¢ã¯ã»ã¹ã§ãã
} ;
struct D2 : D1
{
// virtualåºæ¬ã¯ã©ã¹ã®Baseã®ãã¹ãã©ã¯ã¿ã¼ã«ã¢ã¯ã»ã¹ã§ããªã
// ãã¹ãã©ã¯ã¿ã¼ã¯æé»ã«deleteå®ç¾©ããã
} ;
int main()
{
D1 d1 ; // OKãæé»ã®ãã¹ãã©ã¯ã¿ã¼ã使ã
D2 d2 ; // ã¨ã©ã¼ããã¹ãã©ã¯ã¿ã¼ã¯deleteå®ç¾©ããã¦ãã
}
D2ããD1ã®ãã¹ãã©ã¯ã¿ã¼ã«ã¢ã¯ã»ã¹ãããã¨ã¯ã§ããããD2ããvirtualåºæ¬ã¯ã©ã¹ã§ããBaseã®ãã¹ãã©ã¯ã¿ã¼ã«ã¢ã¯ã»ã¹åºæ¥ãªããããD2ã®ãã¹ãã©ã¯ã¿ã¼ã¯æé»ã«deleteå®ç¾©ãããã
ãã¹ãã©ã¯ã¿ã¼ãããªãã¢ã«ã¨ãªãããã«ã¯ãã¦ã¼ã¶ã¼æä¾ãdeleteå®ç¾©ãããã¦ãããã以ä¸ã®æ¡ä»¶ããã¹ã¦æºããå¿
è¦ãããã
- ãã¹ãã©ã¯ã¿ã¼ã¯virtualã§ã¯ãªãã
- ç´æ¥ã®åºæ¬ã¯ã©ã¹ã®ãã¹ãã©ã¯ã¿ã¼ã¯ããã¹ã¦ããªãã¢ã«ã§ããã
- éstaticãã¼ã¿ã¡ã³ãã¼ã®ãã¹ãã©ã¯ã¿ã¼ã¯ããã¹ã¦ããªãã¢ã«ã§ããã
注æãã¹ããã¨ã¨ãã¦ã¯ãç´æ¥ã®åºæ¬ã¯ã©ã¹ã®ãã¹ãã©ã¯ã¿ã¼ãããªãã¢ã«ã¨ãªãããã«ã¯ãç´æ¥ã®åºæ¬ã¯ã©ã¹ã®ç´æ¥ã®åºæ¬ã¯ã©ã¹ã®ãã¹ãã©ã¯ã¿ã¼ãããªãã¢ã«ã§ãªããã°ãªããªããã¤ã¾ããæçµçã«ã¯ãéæ¥ã®åºæ¬ã¯ã©ã¹ã®ãã¹ãã©ã¯ã¿ã¼ãããã¹ã¦ããªãã¢ã«ã§ãªããã°ãªããªãã
deleteå®ç¾©ããã¦ããªãæé»ã®ãã¹ãã©ã¯ã¿ã¼ã¯ã使ãããã¨ãã«ãå®ç¾©ãããããããã¯ãæ示çã«defaultåãããã¨ãã«ãå®ç¾©ãããã
ãã¹ãã©ã¯ã¿ã¼ã®å¼ã³åºãã¯ãã³ã³ã¹ãã©ã¯ã¿ã¼å¼ã³åºãã®éé ã«è¡ããããã³ã³ã¹ãã©ã¯ã¿ã¼å¼ã³åºãã®é çªã«ã¤ãã¦ã¯ãåºæ¬ã¯ã©ã¹ã¨ãã¼ã¿ã¡ã³ãã¼ã®åæåãåç
§ã
ã¯ã©ã¹ã®ãã¹ãã©ã¯ã¿ã¼ã®æ¬ä½ã®å®è¡ãçµããæ¬ä½å
ã®èªåå¤æ°ãç ´æ£ãããå
±ç¨ã¡ã³ãã¼ãé¤ãã¯ã©ã¹ã®ç´æ¥ã®ã¡ã³ãã¼ã«å¯¾ãã¦ããã¹ãã©ã¯ã¿ã¼ãå¼ã³åºããã¯ã©ã¹ã®ç´æ¥ã®åºæ¬ã¯ã©ã¹ã®ãã¹ãã©ã¯ã¿ã¼ãå¼ã³åºããã¯ã©ã¹ããæä¸ä½ã®æ´¾çã¯ã©ã¹ãªãã°ãvirtualåºæ¬ã¯ã©ã¹ã®ãã¹ãã©ã¯ã¿ã¼ãå¼ã³åºãã
é
åã®è¦ç´ ã«å¯¾ãããã¹ãã©ã¯ã¿ã¼ããã³ã³ã¹ãã©ã¯ã¿ã¼ã®éé ã«å¼ã°ããã
ãã¹ãã©ã¯ã¿ã¼ã¯ãvirtualé¢æ°ããã¥ã¢virtualé¢æ°ã«ãããã¨ãã§ãããåºæ¬ã¯ã©ã¹ã®ãã¹ãã©ã¯ã¿ã¼ãvirtualé¢æ°ã§ããå ´åãæ´¾çã¯ã©ã¹ã®ãã¹ãã©ã¯ã¿ã¼ãvirtualã«ãªããåºæ¬ã¯ã©ã¹ã®ãã¹ãã©ã¯ã¿ã¼ããã¥ã¢virtualé¢æ°ã®å ´åãæ´¾çã¯ã©ã¹ã®ãªãã¸ã§ã¯ããæ§ç¯ããããã«ã¯ããã¹ãã©ã¯ã¿ã¼ãå®ç¾©ããªããã°ãªããªãããããã¯ãé常ã®virtualé¢æ°ã¨å¤ãããªãã
struct Base
{
virtual ~Base() { } // ãã¹ãã©ã¯ã¿ã¼ã¯virtualé¢æ°
} ;
struct Derived : Base
{
~Derived() { } // ãã¹ãã©ã¯ã¿ã¼ã¯virtualé¢æ°
} ;
struct Abstract_base
{
virtual ~Abstract_base() = 0 ; // ãã¹ãã©ã¯ã¿ã¼ã¯ãã¥ã¢virtualé¢æ°
} ;
ãã¹ãã©ã¯ã¿ã¼ãvirtualé¢æ°ã«ããç®çã¯ããªãã¸ã§ã¯ãã«åçã«æ§ç¯ãç ´æ£ããéã«ãåæ
å ±ã管çããªãã¦ãããã¨ããç¹ã«ããã
#include <iostream>
struct B1
{
virtual ~B1() { } // virtualé¢æ°
} ;
struct D1 : B1
{
~D1() { std::cout << "D1 destructor" << std::endl ; }
} ;
struct B2
{
~B2() {} // évirtualé¢æ°
} ;
struct D2 : B2
{
~D2() { std::cout << "D2 destructor" << std::endl ; }
} ;
int main()
{
B1 * b1_ptr = new D1 ;
delete b1_ptr ; // æ´¾çã¯ã©ã¹ã®ãã¹ãã©ã¯ã¿ã¼ãå¼ã°ãã
B2 * b2_ptr = new D2 ;
delete b2_ptr ; // æ´¾çã¯ã©ã¹ã®ãã¹ãã©ã¯ã¿ã¼ãå¼ã°ããªã
}
deleteå¼ã«æ¸¡ãã¦ããã®ã¯ãåºæ¬ã¯ã©ã¹ã¸ã®ãã¤ã³ã¿ã¼ã§ããããã®ãããévirtualãªãã¹ãã©ã¯ã¿ã¼ã§ã¯ãæ´¾çã¯ã©ã¹ã®ãã¹ãã©ã¯ã¿ã¼ãå¼ã³åºãããªãããã¹ãã©ã¯ã¿ã¼ãvirtualé¢æ°ã«ãã¦ããã°ããã®ãããªå ´åã«ããæ´¾çã¯ã©ã¹ã®ãã¹ãã©ã¯ã¿ã¼ãæ£ããå¼ã³åºãããã
ãã¹ãã©ã¯ã¿ã¼ãæé»ã«å¼ã°ããæ¡ä»¶ã¯ã以ä¸ã®éãã§ããã
- staticã¹ãã¬ã¼ã¸ä¸ã®ãªãã¸ã§ã¯ãã«å¯¾ãã¦ã¯ãããã°ã©ã ã®çµäºæã«å¼ã°ããã
- threadã¹ãã¬ã¼ã¸ä¸ã®ãªãã¸ã§ã¯ãã«å¯¾ãã¦ã¯ãã¹ã¬ããã®çµäºæã«å¼ã°ããã
- èªåã¹ãã¬ã¼ã¸ä¸ã®ãªãã¸ã§ã¯ãã«å¯¾ãã¦ã¯ããªãã¸ã§ã¯ããæ§ç¯ãããããã¯ãæããã¨ãã«å¼ã°ããã
- ä¸æãªãã¸ã§ã¯ãã«å¯¾ãã¦ã¯ã寿å½ãå°½ããã¨ãã«å¼ã°ããã
- newå¼ã§æ§ç¯ããããªãã¸ã§ã¯ãã«å¯¾ãã¦ã¯ãdeleteå¼ã§ç ´æ£ãããã¨ãã«å¼ã°ãã
- ãã®ä»ãä¾å¤ã¨ãã¦æãããããªãã¸ã§ã¯ãã®ãã£ããã«é¢é£ãã¦å¼ã°ãããã¨ããã
ã¯ã©ã¹åããããã¯ã¯ã©ã¹ã®é
ååã®ãªãã¸ã§ã¯ãã宣è¨ãããç®æã§ãã¯ã©ã¹ã®ãã¹ãã©ã¯ã¿ã«ã¢ã¯ã»ã¹åºæ¥ãªãå ´åã¯ãã¨ã©ã¼ã¨ãªãã
class X
{
private :
~X() { } // privateã¡ã³ãã¼
} ;
int main()
{
X x ; // ã¨ã©ã¼ããã¹ãã©ã¯ã¿ã¼ã«ã¢ã¯ã»ã¹ã§ããªãã
}
ã¯ã©ã¹ãvirtualãã¹ãã©ã¯ã¿ã¼ãæã¤å ´åãã¯ã©ã¹ã«ã¯å¯¾å¿ãã解æ¾é¢æ°ã使ããç¶æ
ã§ãªããã°ãªããªãã解æ¾é¢æ°ã¯ãã¾ãã¯ã©ã¹ã®ã¹ã³ã¼ãå
ã§æ¢ãããè¦ã¤ãããªãå ´åã¯ãã°ãã¼ãã«ã¹ã³ã¼ãã§æ¢ãããã解æ¾é¢æ°ãè¦ã¤ãããªãããææ§ããdeleteå®ç¾©ããã¦ããå ´åãã¨ã©ã¼ã¨ãªããããã¯ããã¨ãããã°ã©ã ä¸ã§deleteå¼ã使ããªãã¦ãã¨ã©ã¼ã¨ãªãã
struct X
{
virtual ~X() { } // OKãã°ãã¼ãã«ã¹ã³ã¼ãã®operator deleteãçºè¦ããã
} ;
struct Y
{
virtual ~Y() { } // ã¨ã©ã¼ãoperator deleteã¯deleteå®ç¾©ããã¦ããã
void operator delete( void * ptr ) = delete ;
} ;
struct B1
{
void operator delete( void * ptr ) ;
virtual ~B1() { }
} ;
struct B2
{
void operator delete( void * ptr ) ;
} ;
struct Derived : B1, B2
{
// ã¨ã©ã¼ãææ§
// æé»ã®ãã¹ãã©ã¯ã¿ã¼ã¯virtualé¢æ°
} ;
ãã®è¦æ ¼ã®æå³ã¯ãåçãªåã®ãªãã¸ã§ã¯ãã¯ã常ã«deleteå¼ãé©ç¨ã§ãããã¨ãä¿è¨¼ããããã§ããã
ãã¹ãã©ã¯ã¿ã¼ã¯ãæ示çã«å¼ã³åºããã¨ãã§ããããã¹ãã©ã¯ã¿ã¼ãæ示çã«å¼ã³åºãã«ã¯ãã¡ã³ãã¼ã¢ã¯ã»ã¹æ¼ç®åã使ãã~ã«ç¶ãã¦ãã¯ã©ã¹åã«å¯¾å¿ããååããdecltypeæå®åã使ãã
// ãã®ã³ã¼ãã¯ãããã¾ã§æ示çãªãã¹ãã©ã¯ã¿ã¼å¼ã³åºãã説æããããã®ä¾ã§ãã
// é¢æ°fãå¼ã³åºãã¨ãXã®ãã¹ãã©ã¯ã¿ã¼ã¯4åå¼ã³åºããããã¨ã«ãªããæåã¯æªå®ç¾©ã§ãã
struct X { } ;
void f()
{
X x ;
x.~X() ; // ãã¹ãã©ã¯ã¿ã¼ã®æ示çãªå¼ã³åºãï¼ååï¼
x.~decltype(x)() ; // ãã¹ãã©ã¯ã¿ã®æ示çãªå¼ã³åºãï¼decltypeæå®åï¼
x.X::~X() ; // 修飾åä»ã
// ãããã¯ãæããéã«ããã¹ãã©ã¯ã¿ã¼ãæé»ã«å¼ã³åºããã
}
ãã¨ããèªåã¹ãã¬ã¼ã¸ä¸ã®ãªãã¸ã§ã¯ãã«å¯¾ãã¦ãã¹ãã©ã¯ã¿ã¼ãæ示çã«å¼ã³åºããã¨ãã¦ãããããã¯ãæããéã«ããã¹ãã©ã¯ã¿ã¼ã¯æé»çã«å¼ã³åºãããããã¹ãã©ã¯ã¿ã¼ãå¼ã³åºããå¾ã®ãªãã¸ã§ã¯ãã«å¯¾ãã¦ãåã³ãã¹ãã©ã¯ã¿ã¼ãå¼ã³åºããå ´åãæåã¯æªå®ç¾©ãªã®ã§ãä¸è¨ã®ã³ã¼ãã®æåããæªå®ç¾©ã§ããã
ä¸è¬ã«ãèªåã¹ãã¬ã¼ã¸ä¸ã®ãªãã¸ã§ã¯ãã«å¯¾ãã¦æ示çã«ãã¹ãã©ã¯ã¿ã¼ãå¼ã³åºããå¾ããã®ãªãã¸ã§ã¯ãã«å¯¾ãã¦ãé常ãªãã°æé»ã«ãã¹ãã©ã¯ã¿ã¼ãå¼ã³åºãããç¶æ³ã«ãªã£ã¦ããå ´åãæåã¯æªå®ç¾©ã§ããã
ãã¹ãã©ã¯ã¿ã¼ã®æ示çãªå¼ã³åºãã¯ãã¾ã使ãå¿
è¦ã¯ãªãããã¹ãã©ã¯ã¿ã¼ãæé»ã«å¼ã³åºããããã¨ããªãå ´åã¨ãã¦ã¯ãplacement newã«ãããã¦ã¼ã¶ã¼æå®ã®ã¹ãã¬ã¼ã¸ä¸ã¸ã®ãªãã¸ã§ã¯ãã®æ§ç¯ãæããããã
#include <new>
struct X
{
~X() { /*å®è£
*/ }
} ;
int main()
{
void * ptr = ::operator new( sizeof(X) ) ; // ã¹ãã¬ã¼ã¸ã確ä¿
X * x_ptr = new(ptr) X ; // ptrã®æãã¹ãã¬ã¼ã¸ä¸ã«Xåã®ãªãã¸ã§ã¯ããæ§ç¯
x_ptr->~X() ; // ãã¹ãã©ã¯ã¿ã¼ã®æ示çãªå¼ã³åºã
::operator delete( ptr ) ; // ã¹ãã¬ã¼ã¸ã®è§£æ¾
}
ã¹ã«ã©ã¼åã«å¯¾ãã¦ãããã¹ãã©ã¯ã¿ã¼ãæ示çã«å¼ã³åºããã¨ãã§ãããããã«ãã£ã¦ããã³ãã¬ã¼ãã®ã³ã¼ãã«ããã¦ãåãçµã¿è¾¼ã¿åã§ãããã©ãããæ°ã«ããªãã¦ããã
int main()
{
typedef int I ;
I i ;
i.~I() ; // OKããªã«ãããªã
}
ãã¹ãã©ã¯ã¿ã¼ãå¼ã³åºããå¾ã®ãªãã¸ã§ã¯ãã«å¯¾ãã¦ãåã³ãã¹ãã©ã¯ã¿ã¼ãå¼ã³åºããå ´åã®æåã¯æªå®ç¾©ã§ããã
ã¯ã©ã¹ã«å¯¾ãã確ä¿é¢æ°ï¼operator newï¼ã¨è§£æ¾é¢æ°ï¼operator deleteï¼ã¯ãã¡ã³ãã¼é¢æ°ã¨ãã¦ãªã¼ãã¼ãã¼ããããã¨ãã§ããã確ä¿é¢æ°ã¨è§£æ¾é¢æ°ã®å
·ä½çãªå®è£
æ¹æ³ã«ã¤ãã¦ã¯ãåçã¡ã¢ãªã¼ç®¡çãåç
§ã
ã¯ã©ã¹ã®ã¡ã³ãã¼é¢æ°ã¨ãã¦ã®ç¢ºä¿é¢æ°ã解æ¾é¢æ°ã¯ãstaticã¡ã³ãã¼é¢æ°ã§ããããã¨ãstaticæå®åãæ示çã«ä½¿ããã¦ããªãã¦ããstaticã¡ã³ãã¼é¢æ°ã¨ãªãã
#include <cstddef>
struct X
{
// 確ä¿é¢æ°
void * operator new ( std::size_t size )
{ return ::operator new( size ) ; }
// é
å
void * operator new[] ( std::size_t size )
{ return ::operator new( size ) ; }
// placement form
void * operator new ( std::size_t size, int, int, int )
{ return ::operator new( size ) ; }
// 解æ¾é¢æ°
void operator delete( void * ptr )
{ ::operator delete ( ptr ) ; }
// é
å
void operator delete[] ( void * ptr )
{ ::operator delete ( ptr ) ; }
// placement form
void operator delete( void * ptr, int, int, int )
{ ::operator delete ( ptr ) ; }
} ;
解æ¾é¢æ°ã«ä¾å¤æå®ããªãå ´åãnoexcept(true)ãæå®ããããã®ã¨ã¿ãªãããã
ãã®é
ç®ã§ã¯ãã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã®åæåã«ã¤ãã¦åãæ±ããç¹ã«ãæ示çã«åæååãæå®ããã¦ãããªãã¸ã§ã¯ãã¨ãã¯ã©ã¹ã®åºæ¬ã¯ã©ã¹ã¨ã¡ã³ãã¼ã®ãµããªãã¸ã§ã¯ãã®åæåæ¹æ³ã解説ããã
ã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã«åæååãæå®ããã¦ããªãå ´åã®åæåæ¹æ³ã¯ãåæååãåç
§ã
ã¯ã©ã¹ãªãã¸ã§ã¯ãã®é
åã®è¦ç´ ãåæåããéã«ã¯ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ãæ·»åã®é çªã«å¼ã°ããããã¹ãã©ã¯ã¿ã¼ã¯ã³ã³ã¹ãã©ã¯ã¿ã¼ã®éé ã«å¼ã°ããã
#include <iostream>
class X
{
private :
int value ;
public :
X( int value ) : value(value) { std::cout << value ; }
~X() { std::cout << value ; }
} ;
int main()
{
X a[3] = { 1, 2, 3 } ;
}
Xåã®é
åã®è¦ç´ ã¯ãa[0], a[1], a[2]ã®é çªã«æ§ç¯ãããa[2], a[1], a[0]ã®é çªã«ç ´æ£ãããããããã£ã¦ãåºåã¯ã123321ã¨ãªãã
ã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã®åæååã«ã¯æ¬å¼§ã«å²ã¾ããå¼ãªã¹ãã使ããã¨ãã§ããããã®å ´åãé©åãªä»®å¼æ°ãªã¹ãã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã«ãã£ã¦åæåãããã
struct X
{
X( int ) ;
X( int, int ) ;
X( int, int, int ) ;
} ;
int main()
{
X x1( 1 ) ; // X::X(int)
X x2( 1, 2 ) ; // X::X(int,int)
X x3( 1, 2, 3 ) ; // X::X(int,int,int)
}
詳ããã¯ãåæååã®ç´æ¥åæåãåç
§ã
ã¾ãã=ï¼ã¤ã³ã¼ã«ï¼è¨å·ã«ç¶ãã¦å¤ãæå®ãããã¨ã§ãåæåãããã¨ãã§ããã
struct X
{
X( int ) ;
} ;
int main()
{
X x = 0 ; // X::X(int)
}
詳ããã¯ãåæååã®ã³ãã¼åæåãåç
§ã
ã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã¯ãåæåãªã¹ãã§åæåãããã¨ãã§ããã
struct X
{
X( int ) { }
} ;
int main()
{
X a[3] = { 1, 2, 3 } ;
}
詳ããã¯ããªã¹ãåæåãåç
§ã
åºæ¬ã¯ã©ã¹ã¯ãã³ã³ã¹ãã©ã¯ã¿ã¼åæååã«ããåæåã§ããããã¼ã¿ã¡ã³ãã¼ã¯ãã³ã³ã¹ãã©ã¯ã¿ã¼åæååããã¡ã³ãã¼ã®å®£è¨ã«ç¶ãåæååã«ãã£ã¦ãåæåã§ãããã¾ããã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ããªã²ã¼ã(Delegate)ã§ããã
ã³ã³ã¹ãã©ã¯ã¿ã¼åæåå
ã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã®å®ç¾©ã§ãç´æ¥ã®åºæ¬ã¯ã©ã¹ãvirtualåºæ¬ã¯ã©ã¹ãéstaticãã¼ã¿ã¡ã³ãã¼ãåæåã§ãããææ³ã¯ã以ä¸ã®ããã«ãªãã
ã³ã³ã¹ãã©ã¯ã¿ã¼åæåå:
: ã¡ã³ãã¼åæåå, ã¡ã³ãã¼åæåå ...opt
ã¡ã³ãã¼åæåå:
ã¡ã³ãã¼åæåèå¥å ( å¼ãªã¹ã )
ã¡ã³ãã¼åæåèå¥å åæåãªã¹ã
ã¡ã³ãã¼åæåèå¥å:
ã¯ã©ã¹å
decltype
èå¥å
struct Base
{
Base( int ) { }
} ;
struct Derived : Base
{
int member1 ;
int member2 ;
Derived()-
// ã³ã³ã¹ãã©ã¯ã¿ã¼åæåå
: Base( 0 ), // åºæ¬ã¯ã©ã¹
member1( 0 ), // ã¡ã³ãã¼
member2{ 0 } // ã¡ã³ãã¼ï¼åæåãªã¹ãï¼
{ }
} ;
é修飾ã®ã¡ã³ãã¼åæåèå¥åã¯ãã¾ãã³ã³ã¹ãã©ã¯ã¿ã¼ã®ã¯ã©ã¹ã®ã¹ã³ã¼ãå
ã§ååæ¢ç´¢ãããè¦ã¤ãããªãã£ãå ´åã¯ãåºæ¬ã¯ã©ã¹ã®ã¹ã³ã¼ãããæ¢ãããããã®ãããåºæ¬ã¯ã©ã¹ã®ååã¨ãã¯ã©ã¹ã®éstaticãã¼ã¿ã¡ã³ãã¼ã®ååãè¡çªããå ´åãå¿
ãã¡ã³ãã¼ã®ååã使ãããããã®å ´åãåºæ¬ã¯ã©ã¹ãæå®ããã«ã¯ã修飾åãç¨ããªããã°ãªããªãã
struct Base { } ;
struct Derived : Base
{
int Base ;
Derived() :
Base(), // Derivedã®éstaticãã¼ã¿ã¡ã³ãã¼
Derived::Base() // åºæ¬ã¯ã©ã¹
{ }
} ;
ã¡ã³ãã¼åæåèå¥åã¨ãã¦ä½¿ããååã¯ãç´æ¥ã®åºæ¬ã¯ã©ã¹ã¨ãvirtualåºæ¬ã¯ã©ã¹ãã³ã³ã¹ãã©ã¯ã¿ã¼ã®ã¯ã©ã¹ã®éstaticãã¼ã¿ã¡ã³ãã¼ã§ããã
struct A { } ;
struct B { } ;
struct C : B, virtual A { } ;
struct D : C
{
D() :
C(), // OK
A() // OK
// Bã¯Dã®ç´æ¥ã®åºæ¬ã¯ã©ã¹ã§ã¯ãªãã®ã§ä½¿ããªã
{ }
} ;
ã¡ã³ãã¼åæååèå¥åã«ã¯ãåºæ¬ã¯ã©ã¹ã®åãæã示ãtypedefåãdecltypeæå®åã使ããã¨ãã§ããã
struct A { } ;
typedef A type ;
struct B { } ;
B b ;
struct C : A, B
{
C() : type(), decltype(b)()
{ }
} ;
è¤æ°ã®å
±ç¨ã¡ã³ãã¼ã®ãã¡ã®ãã²ã¨ã¤ã ãããã¡ã³ãã¼åæååã§åæåãããã¨ãã§ããã
union U
{
int a ; int b ;
U() : a(0) { } // OKãã²ã¨ã¤ã ã
} ;
struct S
{
union { int a ; int b ; } ;
S() : a(0) { } // OK ã²ã¨ã¤ã ã
} ;
union Error
{
int a ; int b ;
Error() : a(0), b(0) // ã¨ã©ã¼ãè¤æ°ã®æå®
{ }
} ;
åãunionã®ã¡ã³ãã¼ã§ããå
±ç¨ã¡ã³ãã¼ã¯ããªãã¸ã§ã¯ãä¸ã®ã¹ãã¬ã¼ã¸ãå
±æãã¦ããã®ã§ãè¤æ°åæåãããã¨ã¯ã§ããªãã
ã¡ã³ãã¼åæååã«ãåãã¡ã³ãã¼åããããã¯åºæ¬ã¯ã©ã¹åããè¤æ°æå®ãããã¨ã¯ã§ããªãã
struct Base { } ;
struct Derived : Base
{
int member ;
Derived()
: member(), member(), // ã¨ã©ã¼ãåãã¡ã³ãã¼å
Base(), Base() // ã¨ã©ã¼ãåãåºæ¬ã¯ã©ã¹å
{ }
} ;
ã³ã³ã¹ãã©ã¯ã¿ã¼ã®ããªã²ã¼ãã«ã¤ãã¦ã¯ãã³ã³ã¹ãã©ã¯ã¿ã¼ã®ããªã²ã¼ããåç
§ã
ã¡ã³ãã¼åæåãæ示çã«æå®ããã¦ããããã¢ãã¹ãã©ã¯ãã¯ã©ã¹ã®virtualåºæ¬ã¯ã©ã¹ã§ããªãéstaticãã¼ã¿ã¡ã³ãã¼ã¨åºæ¬ã¯ã©ã¹ã¯ã次ã®ããã«åæåãããã
éstaticãã¼ã¿ã¡ã³ãã¼ã«åæååãæå®ããã¦ããå ´åãåæååã®æ¹æ³ã«å¾ã£ã¦åæåãããã
struct S
{
int member = 123 ;
S() /*ã¡ã³ãã¼åæååã«ããmemberã®æå®ãªã*/ { }
} ;
ãã®ä¾ã§ã¯ãmemberã¯ã123ã§åæåãããã
å
±ç¨ã¡ã³ãã¼ã®å ´åãåæåãããªãã
union U
{
int member ;
U() /*ã¡ã³ãã¼åæååã«ããå
±ç¨ã¡ã³ãã¼æå®ãªã*/ { }
} ;
struct S
{
union { int member ; } ;
S() /*ã¡ã³ãã¼åæååã«ããå
±ç¨ã¡ã³ãã¼ã®æå®ãªã*/ { }
} ;
union initialize
{
int member ;
initialize() : member(0) { } // memberã0ã§åæå
} ;
å
±ç¨ã¡ã³ãã¼ã«ã¯ãæ示çãªåæåãå¿
è¦ã§ããã
ãã以å¤ã®å ´åãããã©ã«ãåæåãããã
struct X { X() { } } ;
struct S
{
int m1 ;
X m2 ;
S() { }
} ;
ãã®ä¾ã§ã¯ãintåã®éstaticãã¼ã¿ã¡ã³ãã¼m1ã®åæåå¦çã¯ããã©ã«ãåæåã§å®ç¾©ããã¦ããããã«ãä½ãããªããXåm2ã¯ãXåã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã«ãã£ã¦åæåãããã
åãunionã«å±ããéstaticãªå
±ç¨ã¡ã³ãã¼ã¯ãã²ã¨ã¤ããåæåã§ããªãã
union U
{
int m1 ; int m2 ;
U() : m1(0), m2(0) { } // ã¨ã©ã¼
} ;
struct X
{
union { int m1 ; int m2 ; } ;
X() : m1(0), m2(0) { } // ã¨ã©ã¼
} ;
struct Y
{
union { int m1 ; } ;
union { int m2 ; } ;
Y() : m1(0), m2(0) { } // OKãéãunionã®å
±ç¨ã¡ã³ãã¼
} ;
Yã®ä¾ã¯ãéãunionã®å
±ç¨ã¡ã³ãã¼ãªã®ã§ãåé¡ã®ãªãã³ã¼ãã§ããã
ã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã®å®è¡ãçµäºããæç¹ã§ãåæåãæ示çãªå¤ã®è¨å®ãããã¦ããªãã¡ã³ãã¼ã®å¤ã¯ãä¸å®ã§ããã
struct X
{
int member ;
X() { }
} ;
X x1 ; // staticã¹ãã¬ã¼ã¸ä¸ã«æ§ç¯ããããªãã¸ã§ã¯ãã¯ãã¼ãåæåãããã®ã§ãx1.memberã®å¤ã¯0
int main()
{
X x2 ; // x2.memberã®å¤ã¯ä¸å®
}
éstaticãã¼ã¿ã¡ã³ãã¼ã®å®£è¨ã«åæååããããã¡ã³ãã¼åæååãæå®ããã¦ããå ´åãã¡ã³ãã¼åæååãåªå
ãããããã®å ´åãã¡ã³ãã¼å®£è¨ã®åæååã¯ç¡è¦ãããã
struct X
{
int member = 1;
X() { } // memberã¯1ã§åæåããã
X( int arg ) : member( arg ) { } // memberã¯argã§åæåããã
} ;
int main()
{
X x1 ; // x1.memberã®å¤ã¯1
X x2(2) ; // x2.memberã®å¤ã¯2
}
ããªã²ã¼ããã¦ããªãã³ã³ã¹ãã©ã¯ã¿ã¼ã«ãããåæåã¯ã以ä¸ã®ããã«è¡ãããã
ã¾ãå§ãã«ãã¯ã©ã¹ãæãæ´¾çããåã§ããå ´åãvirtualåºæ¬ã¯ã©ã¹ãåæåãããã
struct V { } ;
struct B : virtual V { } ;
struct C : B { } ;
struct D : C { } ;
int main()
{
D d ; // Dã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã§Vãåæåããã
C c ; // Cã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã§Vãåæåãããã
B b ; // Bã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã§Vãåæåãããã
}
virtualåºæ¬ã¯ã©ã¹ã¯ãæãæ´¾çããã¯ã©ã¹ã§åæåãããã¨ãããã¨ã«ã¯ã注æãå¿
è¦ã§ãããä¾ãã°ã以ä¸ã®ãããªå ´åã
struct V
{
int member ;
V( int arg ) : member( arg ) { }
} ;
struct B : virtual V
{
B() : V(1) { }
} ;
struct C : B { } ;
int main()
{
C c ; // ã¨ã©ã¼ãVã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯æé»ã«deleteå®ç¾©ããã¦ããã
}
Vã¯Cã§åæåãããã®ã§ãBã«ããåæåã¯ãç¡è¦ããã¦ãã¾ããCã®ã¡ã³ãã¼åæååã«ã¯ãVã¯è¨è¿°ããã¦ããªãã®ã§ãVã¯ããã©ã«ãåæåããããVã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯æé»ã«deleteå®ç¾©ããã¦ããã®ã§ãã¨ã©ã¼ã¨ãªãã
è¤æ°ã®virtualåºæ¬ã¯ã©ã¹ãæã¤å ´åãåæåã®é çªã¯ã深度åªå
ï¼depth-ï¬rstï¼ãã¤ãå·¦ããå³ï¼left-to-rightï¼ã¨ãªããã深度ãã¨ã¯ãåºæ¬ã¯ã©ã¹ã«è¡ãã»ã©æ·±ããªãããå·¦ããå³ãã¨ã¯ãåºæ¬ã¯ã©ã¹æå®åãªã¹ãã«ç¾ããvirtualåºæ¬ã¯ã©ã¹ã®é çªã§ããã
struct V1 { } ; struct V2 { } ; struct V3 { } ;
struct B : virtual V1, virtual V2 { } ;
struct C : B, virtual V3 { } ;
C c ; // V1, V2, V3ã®é çªã§åæåããã
virtualåºæ¬ã¯ã©ã¹ã®åæåãçµãã£ãå¾ã§ãç´æ¥ã®åºæ¬ã¯ã©ã¹ããåºæ¬ã¯ã©ã¹æå®åãªã¹ãã«ç¾ããé çªã§åæåããããã¡ã³ãã¼åæååã¯ãåæåã®é çªã«å½±é¿ããªãã
struct B1 { } ; struct B2 { } ;
struct D : B1, B2
{
D() : B2(), B1() { }
} ;
D d ; // B1, B2ã®é çªã«åæåããã
ã¡ã³ãã¼åæååã¯ãåæåã®é çªã«ä½ã®å½±é¿ãä¸ããªããã¨ã«æ³¨æããªããã°ãªããªããããã¯ãå¯ä½ç¨ãåæåã«å½±é¿ããããããããªå ´åãåé¡ã«ãªãã
int i ;
struct B1 { B1(int) { } } ;
struct B2 { B2(int) { } } ;
struct D1 : B1, B2
{
D1() : B2(++i), B1(++i) { }
} ;
struct D2 : B2, B1
{
D2() : B2(++i), B1(++i) { }
} ;
int main()
{
i = 0 ;
D1 d1 ; // B1(1)ãB2(2)ã§åæåããã
D2 d2 ; // B2(1)ãB1(2)ã§åæåããã
}
ã¡ã³ãã¼åæååã®é çªã¯ãåºæ¬ã¯ã©ã¹ã®åæåé åºã«å½±é¿ããªãããã®ãããããåºæ¬ã¯ã©ã¹ã®åæåã«ãããå¯ä½ç¨ãã次ã®åºæ¬ã¯ã©ã¹ã®åæåã«å½±é¿ããããããããªã³ã¼ãã§ã¯ãåºæ¬ã¯ã©ã¹ã®è¨è¿°ã®é çªãå¤ããã ãã§ãåæåã®çµæãç°ãªã£ã¦ãã¾ããä¸è¬ã«ãç´æ¥ã®åºæ¬ã¯ã©ã¹ã®åæåã®é çªãä¿è¨¼ããã¦ãããã¨ãåæã«ããã³ã¼ããæ¸ãã¹ãã§ã¯ãªãã
ç´æ¥ã®åºæ¬ã¯ã©ã¹ã®åæåãçµãã£ãå¾ã§ãã¯ã©ã¹å®ç¾©å
ã®éstaticãã¼ã¿ã¡ã³ãã¼ãã宣è¨ããã¦ããé çªã§åæåããããã¡ã³ãã¼åæååã¯ãåæåã®é çªã«å½±é¿ããªãã
struct X
{
int m1 ;
int m2 ;
X() : m2(0), m1(0) { }
} ;
X x ; // m1, m2ã®é çªã§åæåããã
ç´æ¥ã®åºæ¬ã¯ã©ã¹ã®å ´åã¨åãããã¡ã³ãã¼åæååã¯åæåã®é çªã«å½±é¿ããªãã¨ãããã¨ã«æ³¨æããªããã°ãªããªããéstaticãã¼ã¿ã¡ã³ãã¼ã®åæåã®é çªã¯ãã¯ã©ã¹å®ç¾©ã®ä¸ã§ã¡ã³ãã¼ã宣è¨ããã¦ããé çªã§ããããããã£ã¦ãããã¡ã³ãã¼ã®åæåã®å¯ä½ç¨ãã次ã®ã¡ã³ãã¼ã®åæåã«å½±é¿ããããããããªã³ã¼ãã§ã¯ãã¡ã³ãã¼ã®å®£è¨ã®é çªãå¤ããã ãã§ãåæåå¦çãç°ãªã£ã¦ãã¾ããå
·ä½çãªåé¡ä¾ã¯ãç´æ¥ã®åºæ¬ã¯ã©ã¹ã®å ´åã¨åãã§ãããä¸è¬ã«ãéstaticãã¼ã¿ã¡ã³ãã¼ã®åæåã®é çªãä¿è¨¼ããã¦ãããã¨ãåæã«ããã³ã¼ããæ¸ãã¹ãã§ã¯ãªãã
æå¾ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã®æ¬ä½ãå®è¡ãããã
struct V { } ;
struct B { } ;
struct M { } ;
struct D : B, virtual V
{
M m ;
D() { /* ã³ã³ã¹ãã©ã¯ã¿ã¼ã®æ¬ä½*/ }
} ;
D d ; // V, B, m, ã³ã³ã¹ãã©ã¯ã¿ã¼ã®æ¬ä½ã®é çªã§åæåããã
ã¡ã³ãã¼åæååã«ãããååã¯ãã³ã³ã¹ãã©ã¯ã¿ã¼ã®æ¬ä½ã§è©ä¾¡ãããã
int ;
struct X
{
int x ;
int y ;
X() : x(0), y(x) { }
} ;
ã¡ã³ãã¼åæååã§ã¯ãthisã使ããã¨ãã§ããããã ããthisã®åç
§å
ã¯ã¾ã æ§ç¯éä¸ã§ããå ´åãããã®ã§ã注æãå¿
è¦ã§ããã
éstaticã¡ã³ãã¼é¢æ°ã¯ãvirtualé¢æ°ãå«ãã¦ãæ§ç¯ä¸ã®ãªãã¸ã§ã¯ãã§ãã£ã¦ãå¼ã³åºããã¨ãã§ãããã¾ããæ§ç¯éä¸ã®ãªãã¸ã§ã¯ãããtypeidæ¼ç®åãDynamic castï¼Dynamic castï¼ã®ãªãã©ã³ãã«æ¸¡ããã¨ãã§ããã
ãã ããã³ã³ã¹ãã©ã¯ã¿ã¼åæååã«ããã¦ãã¾ã ãã¹ã¦ã®åºæ¬ã¯ã©ã¹ã®åæåãçµãã£ã¦ããªãæç¹ã§ããã®ç¨®ã®æä½ãè¡ã£ãå ´åãçµæã¯æªå®ç¾©ã§ãããããã¯ãéæ¥çã«æä½ãè¡ãããå ´åãå«ãã
struct A { A(int) { } } ;
struct B : A
{
int f() { return 0 ; }
B() : A( f() ) // çµæã¯æªå®ç¾©
{ }
} ;
// éæ¥çã«æä½ãè¡ãããä¾
struct C : A
{
static int call_f( C * ptr ) { return ptr->f() ; }
int f() { return 0 ; }
C() : A( call_f( this ) ) // æªå®ç¾©
{ }
} ;
æ§ç¯ä¸ã®ãªãã¸ã§ã¯ãã«å¯¾ãã¦virtualé¢æ°ãå¼ã³åºããããtypeidãdynamic_castã使ã£ãå ´åã®æåã¯ãçæã¨ç ´æ£ãåç
§ã
ã¡ã³ãã¼åæååã§ã¯ãããã¯å±éã§ããã
template < typename Bases >
struct X : Bases...
{
X() : Bases()...
{ }
} ;
ã¡ã³ãã¼åæåèå¥åã«ãã¯ã©ã¹åãæå®ãããã¨ã«ãã£ã¦ãå¥ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã«åæåå¦çãå§è²ãããã¨ãã§ãããããããã³ã³ã¹ãã©ã¯ã¿ã¼ã®ããªã²ã¼ã(delegate)ã¨ããã
struct X
{
int member ;
X( int value ) : member( value )
{ /* åæåå¦ç */ }
X( double d ) : X(123) // ã³ã³ã¹ãã©ã¯ã¿ã¼ã®ããªã²ã¼ã
{
// 追å ã®å¦ç
}
} ;
ãã®ä¾ã§ã¯ãã³ã³ã¹ãã©ã¯ã¿ã¼X::X(double)ã¯ãåæåå¦çãX::X(int)ã«ããªã²ã¼ããã¦ããã
å¥ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã«ããªã²ã¼ããã¦ããã³ã³ã¹ãã©ã¯ã¿ã¼ã®ãã¨ããããªã²ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼(delegating constructor)ã¨ãããããªã²ã¼ãå
ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã®ãã¨ããã¿ã¼ã²ããã³ã³ã¹ãã©ã¯ã¿ã¼(target constructor)ã¨ãããã¾ããªãã¸ã§ã¯ãã®åæåã®ããã«æåã«å¼ã³åºãããã³ã³ã¹ãã©ã¯ã¿ã¼ã®ãã¨ããæåã®ã³ã³ã¹ãã©ã¯ã¿ã¼(principal constructor)ã¨ããã
struct X
{
X() : X( 0 ) { }
X( int ) : X( 0.0 ) { }
X( double ) { }
} ;
X x ; // åæå
ä¸ã«ä¾ã«ããããXã®ãªãã¸ã§ã¯ãxã®åæåã§ã¯ãæåã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã¨ãã¦ãX::X()ãé¸ã°ãããããã¯ãããªã²ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã§ãããã¿ã¼ã²ããã³ã³ã¹ãã©ã¯ã¿ã¼ã§ããX::X(int)ã«ããªã²ã¼ããããX::X(int)ãããªã²ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã§ãããã¿ã¼ã²ããã³ã³ã¹ãã©ã¯ã¿ã¼ã®X::X(double)ã«ããªã²ã¼ãããã
ããªã²ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ãä»ã®ã¡ã³ãã¼åæåèå¥åãæå®ãã¦ã¯ãªããªãã
struct Base { } ;
struct X : Base
{
int member ;
X() : X( 0 ),
Base(), member(0) // ã¨ã©ã¼ãããªã²ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ä»ã®èå¥åãæå®ã§ããªã
{ }
X( int ) { }
} ;
ã¿ã¼ã²ããã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ããªã¼ãã¼ãã¼ã解決ã«ããé¸ã°ããã
struct X
{
X() : X( 0 ) { } // X::X(int)ãå¼ã¶
X( int ) : X( 0.0 ) { } // X::X(double)ãå¼ã¶
X( double ) { }
} ;
ã¿ã¼ã²ããã³ã³ã¹ãã©ã¯ã¿ã¼ãå¦çãè¿ããå¾ã«ãããªã²ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã®æ¬ä½ãå®è¡ãããã
struct X
{
int member ;
X() : X( 0 )
{ /* å¦ç2 */ }
X( int value ) : member( value )
{ /* å¦ç1 */ }
} ;
X x ;
ãã®ä¾ã§ã¯ããªãã¸ã§ã¯ãxã®åæåã®éãæåã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã¨ãã¦X::X()ãé¸ã°ãããããã¯ããªã²ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã§ãããã¿ã¼ã²ããã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ãX::X(int)ã¨ãªããã¿ã¼ã²ããã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ãé常ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã¨åãããã«åºæ¬ã¯ã©ã¹ãã¡ã³ãã¼ã®åæåãçµããå¾ãã³ã³ã¹ãã©ã¯ã¿ã¼ã®æ¬ä½ãå®è¡ãï¼å¦ç1ï¼ãå¦çãè¿ããã¿ã¼ã²ããã³ã³ã¹ãã©ã¯ã¿ã¼ãå¦çãè¿ããã®ã§ãæåã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã®æ¬ä½ãå®è¡ãããï¼å¦ç2ï¼ã
ããªã²ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ããç´æ¥çã«ãããéæ¥çã«ãããèªåèªèº«ã«ããªã²ã¼ããè¡ã£ãå ´åã¯ãã¨ã©ã¼ã¨ãªãã
struct X
{
X() : X() {} // ã¨ã©ã¼ãç´æ¥çãªèªåèªèº«ã¸ã®ããªã²ã¼ã
} ;
struct Y
{
Y() : Y(0) { } // ã¨ã©ã¼ãéæ¥çãªèªåèªèº«ã¸ã®ããªã²ã¼ã
Y(int) : Y(0.0) { } // ã¨ã©ã¼ãéæ¥çãªèªåèªèº«ã¸ã®ããªã²ã¼ã
Y(double) : Y() { } // ã¨ã©ã¼ãéæ¥çãªèªåèªèº«ã¸ã®ããªã²ã¼ã
} ;
ã¯ã©ã¹Yã¯ãéæ¥çã«ãèªåèªèº«ã¸ã®ããªã²ã¼ããè¡ãä¾ã§ãããããªã²ã¼ãã®ãã¹ããã¤ã¾ãä»ã®ããªã²ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¸ã®ããªã²ã¼ãã¯å¯è½ã§ããããã ããéæ¥çã§ãã£ã¦ããèªåèªèº«ã¸ã®ããªã²ã¼ãã¯èªããããªãã
ã¯ã©ã¹ã®ãªãã¸ã§ã¯ããæ§ç¯ãããåãç ´æ£ãããå¾ããããã¯æ§ç¯ãç ´æ£ã®æä¸ã«ã¯ãããã¤ãæ°ãä»ããªããã°ãªããªããã¨ãããã
éããªãã¢ã«ã³ã³ã¹ãã©ã¯ã¿ã¼ãæã¤ã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã®å®è¡ãå§ã¾ãåã«ãéstaticã¡ã³ãã¼ãåºæ¬ã¯ã©ã¹ã«ã¢ã¯ã»ã¹ããå ´åãæåã¯æªå®ç¾©ã§ããã
struct X
{
X() { } // éããªãã¢ã«ã³ã³ã¹ãã©ã¯ã¿ã¼
int member ;
} ;
int main()
{
X * ptr = static_cast<X *>( operator new( sizeof(X) ) ) ; // åæåããã¦ããªãã¹ãã¬ã¼ã¸
ptr->member ; // æªå®ç¾©
&ptr->member ; // æªå®ç¾©ããã¤ã³ã¿ã¼ãå¾ããã¨ãã§ããªã
new(ptr) X ; // åæå
ptr->member ; // OK
&ptr->member ; // OK
operator delete( ptr ) ;
}
éããªãã¢ã«ãã¹ãã©ã¯ã¿ã¼ãæã¤ã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã®ãã¹ãã©ã¯ã¿ã¼ã®å®è¡ãçµãã£ãå¾ã«ãéstaticã¡ã³ãã¼ãåºæ¬ã¯ã©ã¹ã«ã¢ã¯ã»ã¹ããå ´åãæåã¯æªå®ç¾©ã§ããã
struct X
{
~X() { } // éããªãã¢ã«ãã¹ãã©ã¯ã¿ã¼
int member ;
} ;
int main()
{
X * ptr = static_cast<X *>( operator new( sizeof(X) ) ) ; // åæåããã¦ããªãã¹ãã¬ã¼ã¸
new(ptr) X ; // åæå
ptr->~X() ; // ãã¹ãã©ã¯ã¿ã¼ã®å®è¡
ptr->member ; // æªå®ç¾©
operator delete( ptr ) ;
}
ã¯ã©ã¹ã¸ã®ãã¤ã³ã¿ã¼ããåºæ¬ã¯ã©ã¹ã¸ã®ãã¤ã³ã¿ã¼ã«åå¤æããéã«ã¯ãã¯ã©ã¹ã¨ãã®ãã¹ã¦ã®åºæ¬ã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã®å®è¡ãå§ã¾ã£ã¦ããªããã°ãªããªããã¾ãããã¹ãã©ã¯ã¿ã¼ã®å®è¡ãå®äºãã¦ãã¦ã¯ãªããªããããã§ãªãå ´åã®æåã¯æªå®ç¾©ã§ãããããã¯ãããªãã¢ã«ã¯ã©ã¹ã«ãå½ã¦ã¯ã¾ãã
struct X { } ;
struct Y : X { } ;
int main()
{
Y * y_ptr = static_cast<Y *>( operator new( sizeof(Y) ) ) ; // åæåããã¦ããªãã¹ãã¬ã¼ã¸
X * x_ptr = y_ptr ; // æªå®ç¾©
new (y_ptr) Y ; // åæå
x_ptr = y_ptr ; // OK
y_ptr->~Y() ; // ãã¹ãã©ã¯ã¿ã¼ã®å®è¡
x_ptr = y_ptr ; // æªå®ç¾©
operator delete( y_ptr ) ;
}
ãªãã¸ã§ã¯ãã®æ§ç¯ãç ´æ£ã®éä¸ã§ãã¡ã³ãã¼é¢æ°ãå¼ã³åºããã¨ã¯ã§ããããã ããvirtualé¢æ°ãã³ã³ã¹ãã©ã¯ã¿ã¼ããã¹ãã©ã¯ã¿ã¼ã®ä¸ã§å¼ã³åºãéã«ã¯ã注æãå¿
è¦ã§ãããvirtualé¢æ°ãã³ã³ã¹ãã©ã¯ã¿ã¼ããã¹ãã©ã¯ã¿ã¼ã®ä¸ããããã¯ãã®ä¸ããå¼ã³åºãããé¢æ°å
ã§å¼ã³åºãã¨ããã®ã³ã³ã¹ãã©ã¯ã¿ã¼ãããã¯ãã¹ãã©ã¯ã¿ã¼ã®ã¯ã©ã¹ã®åã«ã¨ã£ã¦ã®ãã¡ã¤ãã«ãªã¼ãã¼ã©ã¤ãã¼ãç¨ããããæ´¾çã¯ã©ã¹ã¯èæ
®ãããªããããã¯ãåºæ¬ã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã®å®è¡ä¸ã«ã¯ãæ´¾çã¯ã©ã¹ã¯ã¾ã å®å
¨ã«åæåããã¦ããªãããã§ããã
struct A
{
virtual void f() { }
virtual void g() { }
// A::fãA::gãå¼ã³åºã
A() { f() ; g() ; }
virtual ~A() { f() ; g() ; }
} ;
struct B : A
{
virtual void f() { }
// B::f, A::gãå¼ã³åºã
B() { f() ; g() ; }
virtual ~B() { f() ; g() ; }
} ;
struct C : B
{
virtual void g() { }
// B::f, C::gãå¼ã³åºã
C() { f() ; g() ; }
virtual ~C() { f() ; g() ; }
} ;
ãã®ä¾ã§ããã¨ãã¯ã©ã¹Cã®ãªãã¸ã§ã¯ããæ§ç¯ããã¨ãã¦ããåºæ¬ã¯ã©ã¹Aã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã®ä¸ã§ã¯A::f, A::gãå¼ã°ãããã¨ã«ãªãã
ãªãã¸ã§ã¯ãã®æ§ç¯ãç ´æ£ã®éä¸ã§ãtypeidæ¼ç®åã使ããã¨ã¯ã§ãããtypeidæ¼ç®åãã³ã³ã¹ãã©ã¯ã¿ã¼ããã¹ãã©ã¯ã¿ã¼ã®ä¸ããããã¯ãã®ä¸ããå¼ã³åºãããé¢æ°å
ã§ä½¿ããã¦ãã¦ãtypeidæ¼ç®åã®ãªãã©ã³ããããã®ã¯ã©ã¹ã®æ§ç¯ä¸ã®ãªãã¸ã§ã¯ãã§ããå ´åãtypeidã¯ã³ã³ã¹ãã©ã¯ã¿ã¼ããã¹ãã©ã¯ã¿ã¼ã®ã¯ã©ã¹åæ
å ±ã表ãstd::type_infoãªãã¸ã§ã¯ããè¿ããããã¯ãåºæ¬ã¯ã©ã¹ã®æ§ç¯ä¸ã¯ãã¾ã æ´¾çã¯ã©ã¹ã¯æ§ç¯ãçµãã£ã¦ããªãããã§ããã
struct A
{
A()
{
typeid( *this ) == typeid( A ) ; // true
}
virtual ~A()
{
typeid( *this ) == typeid( A ) ; // true
}
} ;
struct B : A { } ;
ãã®ä¾ã§ã¯ããã¨ãBã®ãªãã¸ã§ã¯ããæ§ç¯ãããã¨ãã¦ããtypeidã¯Aåã表ãstd::type_infoãªãã¸ã§ã¯ããè¿ãã
ãªãã¸ã§ã¯ãã®æ§ç¯ãç ´æ£ã®éä¸ã§ãdynamic_castã使ããã¨ã¯ã§ãããdynamic_castãã³ã³ã¹ãã©ã¯ã¿ã¼ããã¹ãã©ã¯ã¿ã¼ã®ä¸ããããã¯ãã®ä¸ããå¼ã³åºãããé¢æ°å
ã§ä½¿ããã¦ãã¦ããªãã©ã³ãããã®ã¯ã©ã¹ã®æ§ç¯ä¸ã®ãªãã¸ã§ã¯ãã§ããå ´åãã³ã³ã¹ãã©ã¯ã¿ã¼ããã¹ãã©ã¯ã¿ã¼ã®å±ããã¯ã©ã¹ããæçµçã«æ´¾çãããåã§ããã¨ã¿ãªããããããã¯ãåºæ¬ã¯ã©ã¹ã®æ§ç¯ä¸ã¯ãã¾ã æ´¾çã¯ã©ã¹ã¯æ§ç¯ãçµãã£ã¦ããªãããã§ããã
struct A
{
A() ;
virtual ~A() ;
} ;
struct B : A { } ;
A::A()
{
B * ptr = dynamic_cast<B *>( this ) ; // 常ã«nullãã¤ã³ã¿ã¼
}
A::~A()
{
B * ptr = dynamic_cast<B *>( this ) ; // 常ã«nullãã¤ã³ã¿ã¼
}
ãã¨ããAããæ´¾çãããBåã®ãªãã¸ã§ã¯ãã§ãã£ã¦ããAã®ã³ã³ã¹ãã©ã¯ã¿ã¼ããã¹ãã©ã¯ã¿ã¼ã®ä¸ã§ã¯ãAåãæçµçãªæ´¾çã¯ã©ã¹ã§ããã¨ã¿ãªãããã
ã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã¯ãåæåã¨ä»£å
¥ã«ãã£ã¦ãã³ãã¼ãããã¯ã ã¼ãããããã³ãã¼ãã ã¼ããè¡ãããã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã¨ä»£å
¥æ¼ç®åããããããç¹å¥ã«ãã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ãã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ãã³ãã¼ä»£å
¥æ¼ç®åãã ã¼ã代å
¥æ¼ç®åã¨å¼ã¶ã
ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ï¼copy constructorï¼ã¨ã¯ãããã¯ã©ã¹Xã«ããã¦ãéãã³ãã¬ã¼ããªã³ã³ã¹ãã©ã¯ã¿ã¼ã§ãä¸ã¤ç®ã®ä»®å¼æ°ã®åããX &ãconst X &ãvolatile X &ãconst volatile X &ã®ããããã§ãããäºã¤ç®ä»¥éã®ä»®å¼æ°ã¯åå¨ããªããããã¹ã¦ããã©ã«ãå®å¼æ°ããããã®ãããã
struct X
{
// ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼
X( X & ) ;
X( X const & ) ;
X( X volatile & ) ;
X( X const volatile & ) ;
X( X const &, int x = 0, int y = 0 ) ; // äºã¤ç®ä»¥éã®ä»®å¼æ°ã«ããã©ã«ãå®å¼æ°ããã
// ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ã§ã¯ãªã
X( ) ;
X( int ) ;
template < typename T >
X( T ) ; // ãã³ãã¬ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ã§ã¯ãªã
X( X const &, short ) ; // äºã¤ç®ä»¥éã®ä»®å¼æ°ã«ããã©ã«ãå®å¼æ°ããªã
} ;
ã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ï¼move constructorï¼ã¨ã¯ãããã¯ã©ã¹Xã«ããã¦ãéãã³ãã¬ã¼ããªã³ã³ã¹ãã©ã¯ã¿ã¼ã§ãä¸ã¤ç®ã®ä»®å¼æ°ã®åããX &&ãconst X &&ãvolatile X &&ãconst volatile X &&ã®ããããã§ãããäºã¤ç®ä»¥éã®ä»®å¼æ°ã¯åå¨ããªããããã¹ã¦ããã©ã«ãå®å¼æ°ããããã®ãããã
struct X
{
X( X && ) ;
X( X const && ) ;
X( X volatile && ) ;
X( X const volatile && ) ;
X( X const &&, int x = 0 ) ;
} ;
ã¯ã©ã¹Xã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã®ä¸ã¤ç®ã®ä»®å¼æ°ã®åãXã§ãäºã¤ç®ä»¥éã®ä»®å¼æ°ãåå¨ããªããããã¹ã¦ããã©ã«ãå®å¼æ°ãæå®ããã¦ããå ´åã¯ãã¨ã©ã¼ã¨ãªãã
struct X
{
X( X ) ; // ã¨ã©ã¼
} ;
ã¾ãããã³ãã¬ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã®ã¤ã³ã¹ã¿ã³ã¹åã®çµæãããã®ãããªã·ã°ããã£ã«ãªãå ´åããã®ãã³ãã¬ã¼ãã¯ã¤ã³ã¹ã¿ã³ã¹åãããªãã
struct X
{
template < typename T >
X( T ) { } // X<X>ã¨ããã¤ã³ã¹ã¿ã³ã¹åã¯èµ·ãããªãã
} ;
int main()
{
X a( 0 ) ; // ãã³ãã¬ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã使ãããã
X b( a ) ; // æé»ã®ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ã使ããã
}
ããã¯ã©ã¹ã«ããã¦ãã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ãæ示çã«å®£è¨ããã¦ããªãå ´åãã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ã¯æé»çã«å®£è¨ãããããããã¯ã©ã¹ã«ã¦ã¼ã¶ã¼å®ç¾©ã®ã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ãã ã¼ã代å
¥æ¼ç®åãã³ãã¼ä»£å
¥æ¼ç®åããã¹ãã©ã¯ã¿ã¼ãåå¨ããå ´åãã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ã¯æé»çã«deleteå®ç¾©ããããããã§ãªãå ´åã¯ãdefaultå®ç¾©ãããã
struct A
{
// ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ã¯æé»çã«defaultå®ç¾©ããã
// A( A const & ) = default ;
} ;
struct B
{
B( B && ) ; // ã¦ã¼ã¶ã¼å®ç¾©ã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼
B & operator = ( B && ) ; // ã¦ã¼ã¶ã¼å®ç¾©ã ã¼ã代å
¥æ¼ç®å
B & operator = ( B & ) ; // ã¦ã¼ã¶ã¼å®ç¾©ã³ãã¼ä»£å
¥æ¼ç®å
~B() ; // ã¦ã¼ã¶ã¼å®ç¾©ãã¹ãã©ã¯ã¿ã¼
// ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ã¯æé»çã«deleteå®ç¾©ããã
// B( B const & ) = delete ;
} ;
C++98/03ã§ã¯ãæé»ã®ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ã¦ã¼ã¶ã¼å®ç¾©ã®ã³ãã¼ä»£å
¥æ¼ç®åãã¦ã¼ã¶ã¼å®ç¾©ã®ã ã¼ã代å
¥æ¼ç®åãã¦ã¼ã¶ã¼å®ç¾©ãã¹ãã©ã¯ã¿ã¼ãããå ´åã§ããæé»çã«å®£è¨ããããC++11ã§ã¯ããã®æåã¯éæ¨å¥¨ã«ãªã£ããå°æ¥çã«åãé¤ãããäºå®ã ã
struct S
{
~S() { }
} ;
int main()
{
S s1 ;
// OK: C++98, C++03ã¾ã§
// éæ¨å¥¨: C++11以é
S s2( s1 ) ;
}
çç±ã¯ããã®ãããªã¦ã¼ã¶ã¼å®ç¾©ã®ç¹å¥ãªã¡ã³ãã¼é¢æ°ãããå ´åã¯ã大æµãæé»ã®ããã©ã«ãã®ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ã®æåã¯ã容æã«ããã°ã©ãã³ã°ä¸ã®èª¤ããå¼ãèµ·ããããã§ããã
ã¦ã¼ã¶ã¼å®ç¾©ã®ã³ãã¼ä»£å
¥æ¼ç®åãã¦ã¼ã¶ã¼å®ç¾©ã®ã ã¼ã代å
¥æ¼ç®åãã¦ã¼ã¶ã¼å®ç¾©ãã¹ãã©ã¯ã¿ã¼ãããå ´åã®æé»ã®ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ã®å®£è¨ã¯ãéæ¨å¥¨ã§ãããå°æ¥ã®è¦æ ¼ã§ã¯åãé¤ãããããã®ããããã®ãããªéæ¨å¥¨ã«ä¾åããã³ã¼ããæ¸ãã¦ã¯ãªããªãã
ã¯ã©ã¹Xã®æé»ã®ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ã®ã·ã°ããã£ã¯ãé常ã
X::X( const X & )
ã¨ãªãããã ããç´æ¥ã®åºæ¬ã¯ã©ã¹ãvirtualåºæ¬ã¯ã©ã¹ãéstaticãã¼ã¿ã¡ã³ãã¼ãconst修飾ããã¦ããªãä»®å¼æ°ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ãæã¤å ´åã
X::X( X & )
ã¨ãªãã
struct A
{
A() = default ;
A( A const & ) { }
} ;
struct B : A
{
// æé»ã®ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ã®ã·ã°ããã£
// B( B const & ) = default ;
} ;
struct C
{
C() = default ;
C( C & ) { }
} ;
struct D : C
{
// æé»ã®ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ã®ã·ã°ããã£
// D( D & ) = default ;
} ;
ããã¯ã©ã¹ã«ããã¦ãã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ãæ示çã«å®£è¨ããã¦ããªãå ´åãã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯æé»çã«å®£è¨ãããããããããã¯ã©ã¹ãã¦ã¼ã¶ã¼å®ç¾©ã®ãã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ãã³ãã¼ä»£å
¥æ¼ç®åãã ã¼ã代å
¥æ¼ç®åããã¹ãã©ã¯ã¿ã¼ãæãããã¾ãã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ãdeleteå®ç¾©ããã¦ããªãå ´åãã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯defaultå®ç¾©ãããã
ã¦ã¼ã¶ã¼å®ç¾©ã®ã ã¼ã代å
¥æ¼ç®åãåå¨ããå ´åãã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯æé»çã«defaultå®ç¾©ãããªããããã¯ãããã©ã«ãã®ã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã®æåã¨ãã¦ã¼ã¶ã¼å®ç¾©ã®ã ã¼ã代å
¥æ¼ç®åã®æåãç°ãªãå¯è½æ§ããããããå®å
¨ã®ããã«defaultå®ç¾©ãããªãã®ã§ããã
struct X
{
// ã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯defaultå®ç¾©ãããªã
// ã¦ã¼ã¶ã¼å®ç¾©ã®ã ã¼ã代å
¥æ¼ç®å
X & operator = ( X && obj )
{
// ã¦ã¼ã¶ã¼å®ç¾©ã®ã ã¼ããå®è£
}
} ;
ãã®ãããèªåå®è£
ã®ã ã¼ãæ§ç¯ã¨ã ã¼ã代å
¥ãè¡ãããå ´åãã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¨ã ã¼ã代å
¥æ¼ç®åã両æ¹ã¦ã¼ã¶ã¼å®ç¾©ããå¿
è¦ãããã
ã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ããæé»ã«ãæ示çã«ã宣è¨ããã¦ããªãå ´åãã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ãå¼ã³åºãå¼ã¯ã代ããã«ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ãå¼ã³åºãã
struct X
{
X() = default ;
// ã¦ã¼ã¶ã¼å®ç¾©ã®ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼
X( X const & ) { }
// ã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯å®£è¨ãããªã
} ;
int main()
{
X a ;
// ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ãå¼ã³åºã
X b( static_cast< X && >( a ) ) ;
}
ã¯ã©ã¹Xã®æé»ã®ã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã®ã·ã°ããã£ã¯ã以ä¸ã®éãã§ããã
X::X( X && )
ããã¯ã©ã¹ã以ä¸ã®æ¡ä»¶ãæºãããæã対å¿ããã³ãã¼/ã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯deleteå®ç¾©ããããã¤ã¾ãã以ä¸ã®æ¡ä»¶ã§ã³ãã¼ãã§ããªãå ´åã¯ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ããã ã¼ããã§ããªãã¨ãã¯ã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ããããããåå¥ã«deleteå®ç¾©ãããã
-
ã¯ã©ã¹ãunionã®ãããªã¯ã©ã¹ã§ãå
±ç¨ã¡ã³ãã¼ãããããéããªãã¢ã«ãªã³ãã¼/ã ã¼ãã»ã³ã³ã¹ãã©ã¯ã¿ã¼ãæã¤å ´å
struct NonTrivial
{
NonTrivial( NonTrivial const & ) { }
NonTrivial( NonTrivial && ) { }
} ;
struct X
{
X() { }
union { NonTrivial n ; } ;
// ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ãnãéããªãã¢ã«ãªã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ãæã¤ããã«deleteå®ç¾©ããã
// ã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ãnãéããªãã¢ã«ãªã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ãæã¤ããã«deleteå®ç¾©ãããã
} ;
-
éstaticãã¼ã¿ã¡ã³ãã¼ãããªã¼ãã¼ãã¼ã解決ã®çµæãã³ãã¼/ã ã¼ãã§ããªãå ´å
ãªã¼ãã¼ãã¼ã解決ã®çµæã¨ããã®ã¯ãè¤æ°ã®åè£ããã£ã¦ææ§ã§ããå ´åãé¸ã°ããæé©é¢æ°ãdeletedå®ç¾©ããã¦ããå ´åãã¢ã¯ã»ã¹æå®ã«ããã¯ã©ã¹ã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ããã¯å©ç¨ã§ããªãå ´åã ã
// ã³ãã¼ã§ããªã
struct uncopyable
{
uncopyable( uncopyable const & ) = delete ;
} ;
// ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ãdeleteå®ç¾©ããã
struct S
{
uncopyable member ;
} ;
ã¢ã¯ã»ã¹æå®ã«ããã¯ã©ã¹ã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ããã¯å©ç¨ã§ããªãå ´åã®ä¾
struct private_copy
{
private :
private_copy( private_copy const & ) = delete ;
} ;
// ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ãdeleteå®ç¾©ããã
struct S
{
// memberã®ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ã¯
// ã¯ã©ã¹Sã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ããã¢ã¯ã»ã¹ã§ããªã
private_copy member ;
} ;
-
ç´æ¥ããããã¯virtualãªåºæ¬ã¯ã©ã¹ãããªã¼ãã¼ãã¼ã解決ã®çµæãã³ãã¼/ã ã¼ãã§ããªãå ´å
-
ç´æ¥ããããã¯virtualãªåºæ¬ã¯ã©ã¹ããããã¯éstaticãã¼ã¿ã¡ã³ãã¼ã®ããã¹ãã©ã¯ã¿ã¼ããdeleteå®ç¾©ã§ãããããããã¯ã¢ã¯ã»ã¹æå®ã«ãããããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ããã¢ã¯ã»ã¹ã§ããªãå ´å
// ãã¹ãã©ã¯ã¿ã¼ãprivateã¡ã³ãã¼ã®ã¯ã©ã¹
struct M
{
private :
~M() { }
} ;
// ã³ãã¼ã¨ã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ãdeleteå®ç¾©ããã
struct S
{
M m ;
} ;
-
éstaticãã¼ã¿ã¡ã³ãã¼ãrvalueãªãã¡ã¬ã³ã¹åã§ããå ´åãã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ãdeleteå®ç¾©ãããã
// ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ãdeleteå®ç¾©ããã
struct S
{
static int data ;
// rvalueãªãã¡ã¬ã³ã¹åã®éstaticãã¼ã¿ã¡ã³ãã¼
int && rref ;
S() : rref( static_cast< int && >(data) ) { }
} ;
int S::data ;
int main()
{
S s1 ;
S s2 = s1 ; // ã¨ã©ã¼ãã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ãdeleteå®ç¾©ããã¦ãã
}
ããã©ã«ãå®ç¾©ãããã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ãdeletedå®ç¾©ããã¦ããå ´åããªã¼ãã¼ãã¼ã解決ã§ã¯ç¡è¦ãããã
ã³ãã¼/ã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ãããªãã¢ã«(trivial)ã¨ãªãã«ã¯ãã¦ã¼ã¶ã¼å®ç¾©ããããä»®å¼æ°ãªã¹ããæé»ã«å®£è¨ãããå ´åã®ä»®å¼æ°ãªã¹ãã¨åãã§ã以ä¸ã®æ¡ä»¶ããã¹ã¦æºããå¿
è¦ãããã
-
ã¯ã©ã¹ã¯virtualé¢æ°ã¨virtualåºæ¬ã¯ã©ã¹ãæããªããã¨
-
volatile修飾ãããéstaticãã¼ã¿ã¡ã³ãã¼ãæããªããã¨
-
ç´æ¥ã®åºæ¬ã¯ã©ã¹ã®ãµããªãã¸ã§ã¯ããã³ãã¼/ã ã¼ãããã®ã«ä½¿ãããã³ã³ã¹ãã©ã¯ã¿ã¼ãããªãã¢ã«ã§ãããã¨
-
ã¯ã©ã¹åããã¯ã©ã¹ã®é
ååã®éstaticãã¼ã¿ã¡ã³ãã¼ãã³ãã¼/ã ã¼ãããã®ã«ä½¿ãããã³ã³ã¹ãã©ã¯ã¿ã¼ãããªãã¢ã«ã§ãããã¨
ãããã®æ¡ä»¶ããã¹ã¦æºãããªãéããã³ãã¼/ã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ãéããªãã¢ã«(non-trivial)ã§ããã
ã³ãã¼/ã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ããdefaultåããã¦ãã¦ãå®ç¾©ãdeletedå®ç¾©ãããã¦ããªãå ´åãODRã®æèã§ä½¿ãããããæåã®å®£è¨ã§æ示çã«defaultåãããå ´åãæé»ã«å®ç¾©ããã(implicitly defined)ããããæé»ã«å®ç¾©ãããã³ã³ã¹ãã©ã¯ã¿ã¼ãconstexprã³ã³ã¹ãã©ã¯ã¿ã¼ã®å¶ç´ãæºããã®ãªãã°ãæé»ã«å®ç¾©ãããã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ãconstexprã³ã³ã¹ãã©ã¯ã¿ã¼ã«ãªãã
ã³ãã¼/ã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ãæé»ã«å®ç¾©ãããããã«ã¯ãç´æ¥ã®åºæ¬ã¯ã©ã¹ãvirtualåºæ¬ã¯ã©ã¹ãéstaticãã¼ã¿ã¡ã³ãã¼ã®ãã¦ã¼ã¶ã¼æä¾ããã¦ããªãã³ãã¼/ã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ããã¹ã¦æé»ã«å®ç¾©ããã¦ããªããã°ãªããªããã¦ã¼ã¶ã¼æä¾ããã¦ããå ´åã¯ãæé»ã«å®ç¾©ããã¦ããªãã¦ãããã
struct Base
{
// ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ã¯æé»ã«å®ç¾©ããã¦ããªã
Base( const Base & ) = delete ;
} ;
struct Derived : Base
{
// ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ã¯æé»ã«defaultåããã
} ;
void f()
{
Derived d1 ;
Derived d2 = d1 ; // ã¨ã©ã¼ãã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ã¯æé»ã«å®ç¾©ããã¦ããªã
}
unionã§ã¯ãªãã¯ã©ã¹ã®æé»ã«å®ç¾©ãããã³ãã¼/ã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ããåºæ¬ã¯ã©ã¹ã¨ã¡ã³ãã¼ã«å¯¾ããã¡ã³ãã¼ãã¨ã®ã³ãã¼/ã ã¼ããè¡ããåæåã®é çªã¯ãã¦ã¼ã¶ã¼å®ç¾©ãããã³ã³ã¹ãã©ã¯ã¿ã¼ã®å ´åã¨åãã§ããã
unionåã®æé»ã«å®ç¾©ãããã³ãã¼/ã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ãunionåã®ãªãã¸ã§ã¯ãã®å
é¨è¡¨ç¾ãã³ãã¼ããã
ã¦ã¼ã¶ã¼å®£è¨ãããã¯ã©ã¹Xã®ã³ãã¼/ã ã¼ã代å
¥æ¼ç®åãX::operator =ã¯ãã¯ã©ã¹Xã®éstaticãéãã³ãã¬ã¼ãã®ã¡ã³ãã¼é¢æ°ã§ãä»®å¼æ°ãä¸ã¤ã ãåãããã®åã¯X, X &, const X &, volatile X & const volatile X &ã§ãªããã°ãªããªãã
struct X
{
X & operator = ( X & ) ;
X & operator = ( X const & ) ;
X & operator = ( X volatile & ) ;
X & operator = ( X const volatile & ) ;
} ;
ã¦ã¼ã¶ã¼å®£è¨ãããã³ãã¼/ã ã¼ã代å
¥æ¼ç®åã®æ»ãå¤ã®åã¯å¶éããã¦ããªãã
struct X
{
// OK
void operator = ( X const & ) { }
} ;
void f()
{
X x1 ;
X x2 ;
x1 = x2 ; // OKãçµæã®åã¯void
}
ã³ã³ã¹ãã©ã¯ã¿ã¼ã¨åããã代å
¥æ¼ç®åã§ãã代å
¥æ¼ç®åã®ãã³ãã¬ã¼ãã¯ãã³ãã¼/ã ã¼ã代å
¥æ¼ç®åã§ã¯ãªãããã ããã³ã³ã¹ãã©ã¯ã¿ã¼ã¨åãããã«ããã³ãã¬ã¼ãã®ç¹æ®åãã³ãã¼/ã ã¼ã代å
¥æ¼ç®åã¨åãä»®å¼æ°ã«ãªã£ãå ´åã¯ããªã¼ãã¼ãã¼ã解決ã®åè£ã¨ãªããéãã³ãã¬ã¼ãã®ã³ãã¼/ã ã¼ã代å
¥æ¼ç®åããåªå
ãã¦é¸æããããã¨ãããããã®ããã代å
¥æ¼ç®åã®ãã³ãã¬ã¼ãã¯ãã³ãã¼é¢¨/ã ã¼ã風ã®ä»£å
¥æ¼ç®åã¨éå
¬å¼ã«å¼ã°ãã¦ããã
struct X
{
X() { }
X & operator = ( X const & ) ; // #1
template < typename T >
X & operator = ( T & ) ; // #2
} ;
void f()
{
X x1 ;
X x2 ;
x1 = x2 ; // #2ãå¼ã°ãã
}
ãããã¯ã©ã¹å®ç¾©ã®ä¸ã§ã³ãã¼ä»£å
¥æ¼ç®åãæ示çã«å®£è¨ããã¦ããªãå ´åãã³ãã¼ä»£å
¥æ¼ç®åã¯æé»çã«å®£è¨ãããã
struct X
{
// ã³ãã¼ä»£å
¥æ¼ç®åãæé»çã«å®£è¨ããã
} ;
ãããã¯ã©ã¹å®ç¾©ã§ãã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ãã ã¼ã代å
¥æ¼ç®åãã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ããã¹ãã©ã¯ã¿ã¼ãã¦ã¼ã¶ã¼å®£è¨ããã¦ããå ´åãæé»ã«å®£è¨ãããã³ãã¼ä»£å
¥æ¼ç®åã¯ãdeleteå®ç¾©ãããã
struct A
{
// ã³ãã¼ä»£å
¥æ¼ç®åã¯deleteå®ç¾©ããã
A( A && ) ;
} ;
struct B
{
// ã³ãã¼ä»£å
¥æ¼ç®åã¯deleteå®ç¾©ããã
B & operator = ( B && ) ;
} ;
C++11ã§ã¯ãã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ããã¹ãã©ã¯ã¿ã¼ãã¦ã¼ã¶ã¼å®£è¨ããã¦ããå ´åãã³ãã¼ä»£å
¥æ¼ç®åã¯defaultåãããããã®æåã¯éæ¨å¥¨ã§ãããå°æ¥çã«ã¯åãé¤ãããããã®ãããªéæ¨å¥¨ã®æ©è½ã«é ¼ã£ãã³ã¼ããæ¸ãã¦ã¯ãªããªãã
// ãã®ãããªã³ã¼ããæ¸ãã¦ã¯ãªããªã
struct X
{
// C++11ã§ã¯ãã³ãã¼ä»£å
¥æ¼ç®åã¯æé»ã«defaultåããã
// ãã®æ©è½ã¯éæ¨å¥¨ã§ããã使ã£ã¦ã¯ãªããªã
X( X const & ) ;
~X() ;
} ;
æé»ã«å®£è¨ããããã¯ã©ã¹Xã®ã³ãã¼ä»£å
¥æ¼ç®åã¯ã以ä¸ã®æ¡ä»¶ã
-
ã¯ã©ã¹Xã®ç´æ¥ã®åºæ¬ã¯ã©ã¹Bããä»®å¼æ°ã®åã¨ãã¦const B &, const volatile B &, Bã®ããããã§ããã³ãã¼ä»£å
¥æ¼ç®åãæã¤
struct B1 { B1 & operator = ( const B & ) ; } ;
struct B2 { B2 & operator = ( const volatile B & ) ; } ;
struct B3 { B3 & operator = ( B ) ; } ;
struct X : B1, B2, B3 { } ;
-
Xã®éstaticãã¼ã¿ã¡ã³ãã¼ããããã¯é
åããã¹ã¦ãåãMã¨ããã¨ãä»®å¼æ°ã®åãconst M &, const volatile M &, Mã§ããã³ãã¼ä»£å
¥æ¼ç®åãæã¤
ããã¹ã¦æºããå ´åã
X & X::operator = ( const X & )
ã®å½¢ãåãã
ä¸ã®æ¡ä»¶ãæºãããªãå ´åãæé»ã«å®£è¨ãããã¯ã©ã¹Xã®ã³ãã¼ä»£å
¥æ¼ç®åã®å½¢ã¯ã
X & X::operator = ( X & )
ã¨ãªãã
ã¯ã©ã¹Xã®ã¦ã¼ã¶ã¼å®£è¨ãããã ã¼ã代å
¥æ¼ç®åãX::operator =ã¯ãéstaticãéãã³ãã¬ã¼ãã®ã¡ã³ãã¼é¢æ°ã§ãä»®å¼æ°ãä¸ã¤ã ãåãããã®åã¯ãX &&, const X &&, volatile X &&, const volatile X &&ã§ãªããã°ãªããªãã
ããã¯ã©ã¹Xã®å®ç¾©ã§ã ã¼ã代å
¥æ¼ç®åãæ示çã«å®£è¨ããã¦ããªãå ´åã¯ã以ä¸ã®æ¡ä»¶ããã¹ã¦æºãããæãæé»çã«ã ã¼ã代å
¥æ¼ç®åã宣è¨ãããã
-
ã¯ã©ã¹Xã¯ã¦ã¼ã¶ã¼å®£è¨ãããã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ãæããªã
-
ã¯ã©ã¹Xã¯ã¦ã¼ã¶ã¼å®£è¨ãããã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ãæããªã
-
ã¯ã©ã¹Xã¯ã¦ã¼ã¶ã¼å®£è¨ãããã³ãã¼ä»£å
¥æ¼ç®åãæããªã
-
ã¯ã©ã¹Xã¯ã¦ã¼ã¶ã¼å®£è¨ããããã¹ãã©ã¯ã¿ã¼ãæããªã
-
ã ã¼ã代å
¥æ¼ç®åã¯æé»ã«deleteå®ç¾©ããã¦ããªã
æé»ã«å®£è¨ãããã¯ã©ã¹Xã®ã ã¼ã代å
¥æ¼ç®åã¯ã以ä¸ã®å½¢ãåãã
X & X::operator = ( X && )
æé»ã«å®£è¨ãããã¯ã©ã¹Xã®ã³ãã¼/ã ã¼ã代å
¥æ¼ç®åã¯ãX &åã®æ»ãå¤ãè¿ããæ»ãå¤ã¨ãã¦è¿ãããã®ã¯ä»£å
¥æ¼ç®åãå¼ã°ããã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã¸ã®ãªãã¡ã¬ã³ã¹ã§ãããæé»ã«å®£è¨ãããã³ãã¼/ã ã¼ã代å
¥æ¼ç®åã¯ãã¯ã©ã¹ã®inline publicã¡ã³ãã¼ã¨ãªãã
ããã©ã«ãåãããã¯ã©ã¹Xã®ã³ãã¼/ã ã¼ã代å
¥æ¼ç®åã¯ãã¯ã©ã¹Xã以ä¸ã®ããããã®ã¡ã³ãã¼ãæã¤æããããã対å¿ããã³ãã¼/ã ã¼ã代å
¥æ¼ç®åããdeleteå®ç¾©ãããã
-
ã¯ã©ã¹Xãunion風ã¯ã©ã¹ã§ããã®å
±ç¨ã¡ã³ãã¼ã«ãéããªãã¢ã«ãªã³ãã¼/ã ã¼ã代å
¥æ¼ç®åãããã¨ã
union風ã¯ã©ã¹ã¨ã¯ãunionãç¡åunionãå«ãã¯ã©ã¹ã§ããã
// éããªãã¢ã«ãªã³ãã¼ä»£å
¥æ¼ç®åãæã¤å
struct S
{
S & operator = ( S const & ) { }
} ;
union U1 { S s ; } ;
struct U2
{
union { S s ; } ;
} ;
int main()
{
U1 a ;
U1 b ;
a = b ; // ã¨ã©ã¼ãã³ãã¼ä»£å
¥æ¼ç®åãdeleteå®ç¾©ããã¦ãã
U2 c ;
U2 d ;
c = d ; // ã¨ã©ã¼ãã³ãã¼ä»£å
¥æ¼ç®åãdeleteå®ç¾©ããã¦ãã
}
-
const修飾ãããéã¯ã©ã¹ã®ãåãé
ååããéstaticãã¼ã¿ã¡ã³ãã¼ã¨ãã¦æã¤å ´å
struct S
{
const int member ;
const int array[10] ;
} ;
-
ãªãã¡ã¬ã³ã¹åã®éstaticãã¼ã¿ã¡ã³ãã¼ãæã¤å ´å
-
ãªã¼ãã¼ãã¼ã解決ã®çµæãã³ãã¼/ã ã¼ã代å
¥ã§ããªãã¯ã©ã¹åãéstaticãã¼ã¿ã¡ã³ãã¼ã¨ãã¦æã¤å ´åã
ã³ãã¼/ã ã¼ã代å
¥ã§ããªãã¨ããã®ã¯ããªã¼ãã¼ãã¼ã解決ã®çµæãææ§ã§ããããæé©åè£ãdeletedå®ç¾©ã§ããããã¢ã¯ã»ã¹æå®ã«ãããã¯ã©ã¹Xã®ããã©ã«ã代å
¥æ¼ç®åããã¢ã¯ã»ã¹ã§ããªãå ´åãããã以ä¸åã
-
ç´æ¥ããããã¯virtualãªåºæ¬ã¯ã©ã¹ãããªã¼ãã¼ãã¼ã解決ã®çµæãã³ãã¼/ã ã¼ã代å
¥ã§ããªãå ´åã
ããã©ã«ãåãããã ã¼ã代å
¥æ¼ç®åãdeleteå®ç¾©ãããå ´åããªã¼ãã¼ãã¼ã解決ã§ã¯ç¡è¦ãããã
ã³ãã¼/ã ã¼ã代å
¥æ¼ç®åã¯ãæ示çã«å®£è¨ãããªãã£ãå ´åãå¿
ãæé»çã«å®£è¨ãããã宣è¨ã®æ¹æ³ã¯æ§ã
ã§ãdeleteå®ç¾©ã«ãªããã¨ããããã宣è¨ããããã¨ã¯ããããããã¯ãã¯ã©ã¹ã®åºæ¬ã¯ã©ã¹ã®ä»£å
¥æ¼ç®åã¯ãå¿
ãé ãããã¨ãããã¨ã ãusing宣è¨ã使ã£ã¦åºæ¬ã¯ã©ã¹ã®ä»£å
¥æ¼ç®åãã¯ã©ã¹ã¹ã³ã¼ãã«å°å
¥ãã¦ãããã®ã¯ã©ã¹ã§å®£è¨ããã代å
¥æ¼ç®åãåªå
ãããããããã¯ãé ãããã
ããã¯ã©ã¹Xã®ã³ãã¼/ã ã¼ã代å
¥æ¼ç®åãããªãã¢ã«ã§ããããã«ã¯ãã¦ã¼ã¶ã¼æä¾ããããä»®å¼æ°ãªã¹ãããæé»ã«å®£è¨ãããå ´åã®ä»®å¼æ°ãªã¹ãã¨åãã§ãããã«ä»¥ä¸ã®æ¡ä»¶ããã¹ã¦æºãããªããã°ãªããªãã
-
ã¯ã©ã¹Xã¯virtualé¢æ°ãæãããvirtualåºæ¬ã¯ã©ã¹ãæããªã
-
ã¯ã©ã¹Xã¯volatile修飾ãããåã®éstaticãã¼ã¿ã¡ã³ãã¼ãæããªã
-
ç´æ¥ã®åºæ¬ã¯ã©ã¹ã®ãµããªãã¸ã§ã¯ãã§ä½¿ãããã³ãã¼/ã ã¼ãã®ä»£å
¥æ¼ç®åãããªãã¢ã«
-
ã¯ã©ã¹Xã®ã¯ã©ã¹åã¨ã¯ã©ã¹ã®é
ååã®éstaticãã¼ã¿ã¡ã³ãã¼ã®ãã³ãã¼/ã ã¼ãã«ä½¿ããã代å
¥æ¼ç®åãããªãã¢ã«
ãã®æ¡ä»¶ãæºãããªãå ´åãã³ãã¼/ã ã¼ã代å
¥æ¼ç®åã¯éããªãã¢ã«ã¨ãªãã
ããã¯ã©ã¹Xã®ãdefaultåããã¦ããããdeleteå®ç¾©ããã¦ããªãã³ãã¼/ã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ãODRã®æèã§ä½¿ãããå ´åããããã¯ãæåã®å®£è¨ã§æ示çã«defaultåãããå ´åãæé»ã«å®ç¾©ãããã
æé»ã«å®ç¾©ãããã³ãã¼/ã ã¼ã代å
¥æ¼ç®åã¯ã以ä¸ã®æ¡ä»¶ããã¹ã¦æºãããå ´åãconstexpré¢æ°ã«ãªãã
-
ã¯ã©ã¹Xã¯ãªãã©ã«å
-
ç´æ¥ã®åºæ¬ã¯ã©ã¹ã®ãµããªãã¸ã§ã¯ãã§ãã³ãã¼/ã ã¼ãã®ããã«ä½¿ããã代å
¥æ¼ç®åããconstexpré¢æ°
-
ã¯ã©ã¹Xã®ãã¯ã©ã¹åããããã¯ã¯ã©ã¹ã®é
ååã®éstaticãã¼ã¿ã¡ã³ãã¼ã®ãã³ãã¼/ã ã¼ãã®ããã«ä½¿ããã代å
¥æ¼ç®åããconstexpré¢æ°
ããã¯ã©ã¹ã®ããã©ã«ãåãããã³ãã¼/ã ã¼ã代å
¥æ¼ç®åãæé»ã«å®ç¾©ãããã«ã¯ãã¯ã©ã¹ã®ç´æ¥ã®åºæ¬ã¯ã©ã¹ã¨ãéstaticãã¼ã¿ã¡ã³ãã¼ã®ã³ãã¼/ã ã¼ã代å
¥æ¼ç®åã®ãã¡ãã¦ã¼ã¶ã¼æä¾ããã¦ããªããã®ã¯ããã¹ã¦æé»ã«å®ç¾©ããã¦ããªããã°ãªããªãã
union以å¤ã®ã¯ã©ã¹ã§ãæé»ã«å®ç¾©ãããã³ãã¼/ã ã¼ã代å
¥æ¼ç®åã¯ãã¯ã©ã¹ã®ãµããªãã¸ã§ã¯ãã«å¯¾ãã¦ã¡ã³ãã¼ãã¨ã®ã³ãã¼/ã ã¼ããè¡ããã¯ã©ã¹ã®ç´æ¥ã®åºæ¬ã¯ã©ã¹ãã¾ã代å
¥ãããã代å
¥ã®é åºã¯ãåºæ¬ã¯ã©ã¹æå®ã®ãªã¹ãã§å®£è¨ãããé çªã§ããã
struct A { } ;
struct B { } ;
// 代å
¥ãããã¨ãã¯ãA, Bã®é çª
struct C : A, B { } ;
// 代å
¥ãããã¨ãã¯ãB, Aã®é çª
struct D : B, A { } ;
ãã®æ¬¡ã«ãã¯ã©ã¹ã®éstaticãã¼ã¿ã¡ã³ãã¼ããã¯ã©ã¹å®ç¾©ã§å®£è¨ãããé çªã§ä»£å
¥ãããããµããªãã¸ã§ã¯ããã¯ã©ã¹åã®å ´åã¯operator =ãå¼ã³åºããåºæ¬åã®å ´åã¯çµã¿è¾¼ã¿ã®ä»£å
¥æ¼ç®åã使ããé
ååã®å ´åã¯ãè¦ç´ ãã¨ã«ä»£å
¥ãããã
æé»ã«å®ç¾©ãããã³ãã¼ä»£å
¥æ¼ç®åããè¤æ°åæ´¾çããã¦ããvirtualåºæ¬ã¯ã©ã¹ã®ãµããªãã¸ã§ã¯ãã®ã³ãã¼ä»£å
¥æ¼ç®åããæ´¾çãããåæ°ã ãå¼ã³åºããã©ããã¯ãæªè¦å®ã§ããã
struct V
{
V & operator = ( V const & ) ; // #1
} ;
struct A : virtual V { } ;
struct B : virtual V { } ;
struct C : A, B { } ; // æé»ã®ã³ãã¼ä»£å
¥æ¼ç®åãdefaultå®ç¾©ããã
int main()
{
C c1 ;
C c2 ;
c2 = c1 ; // #1ãä¸åº¦å¼ã°ããããäºåº¦å¼ã°ãããã¯ãæªè¦å®
}
ã¯ã©ã¹Cã«ã¯ãVã¯A,Bäºã¤ã®ã¯ã©ã¹ã®virtualåºæ¬ã¯ã©ã¹ã«ãªã£ã¦ãããããã¯ã©ã¹Cã«ã¯ãVã®ãµããªãã¸ã§ã¯ãã¯ã²ã¨ã¤ãããªãããã®å ´åãVã®ã³ãã¼ä»£å
¥æ¼ç®åããä¸åå¼ã°ããã¨ã¯éããªãããã ãäºåå¼ã°ããã¨ãéããªããè¦æ ¼ä¸ããã®å ´åã«ãæé»ã«å®ç¾©ãããã³ãã¼ä»£å
¥æ¼ç®åã¯ãVã®ã³ãã¼ä»£å
¥æ¼ç®åãå¼ã³åºãåæ°ã¯ãä¸åã§ãäºåã§ãè¯ãã
ãªããã ã¼ã代å
¥æ¼ç®åã¯ãvirtualåºæ¬ã¯ã©ã¹ãããå ´åãæé»ã«deleteå®ç¾©ãããã®ã§ããã®æªè¦å®ã¯ãªãã
ãã¡ãããæé»ã®å®ç¾©ã§ã¯ãªããæ示çã«å®ç¾©ããå ´åã¯ãæ示çã«æ¸ããã ãã®åæ°å¼ã³åºãã
unionã®æé»ã«å®ç¾©ãããã³ãã¼ä»£å
¥æ¼ç®åã¯ããªãã¸ã§ã¯ãã®å
é¨è¡¨ç¾ãã³ãã¼ããã
ã³ãã¼/ã ã¼ãã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã代å
¥æ¼ç®åãODRã®æèã§ä½¿ããã¦ãã¦ãã¢ã¯ã»ã¹æå®ã®ããã«ã¢ã¯ã»ã¹ã§ããªãå ´åãã¨ã©ã¼ã¨ãªãã
æ¡ä»¶æ¬¡ç¬¬ã§ãC++ã®å®è£
ã¯ãªãã¸ã§ã¯ãã®ã³ãã¼/ã ã¼ãæ§ç¯ãçç¥ãããã¨ãã§ããããã¨ãããã®ãªãã¸ã§ã¯ãã®ã³ã³ã¹ãã©ã¯ã¿ã¼ããã¹ãã©ã¯ã¿ã¼ããå¯ä½ç¨ãæã£ã¦ããã¨ãã¦ããé æ
®ãªãçç¥ãããããããã³ãã¼çç¥(copy elision)ã¨ãããè¦æ ¼ä¸ã®ç¨èªã¯ãã³ãã¼çç¥ãã ããã³ãã¼ã ãã§ã¯ãªããã ã¼ããçç¥ãããå¯è½æ§ãããã
ã³ãã¼çç¥ã¯ã以ä¸ã®å ´åã«è¨±ããã¦ããã
-
ã¯ã©ã¹ãè¿ãé¢æ°ã®returnæã®ãªãã©ã³ãã®å¼ããé¢æ°ã¨catchå¥ã®ä»®å¼æ°ãé¤ãévolatileã®èªåãªãã¸ã§ã¯ãã®ååã§ãããé¢æ°ã®æ»ãå¤ã®åã¨èªåãªãã¸ã§ã¯ãã®åããã¨ãã«CVé修飾ã®åã§ããå ´åãé¢æ°å
ã®èªåãªãã¸ã§ã¯ãã®ã³ãã¼/ã ã¼ããçç¥ãããé¢æ°ã®æ»ãå¤ã®ãªãã¸ã§ã¯ãã¨ãã¦ç´æ¥ã«æ§ç¯ãããã¨ã許ããã¦ãã
struct S
{
S() { }
S( S const & ) { }
~S() { }
} ;
S f()
{
S s ;
return s ; // ã³ãã¼çç¥ã許ããã¦ãã
}
-
throwå¼ã®ãªãã©ã³ãããé¢æ°ã¨catchå¥ã®ä»®å¼æ°ãé¤ãévolatileã®èªåãªãã¸ã§ã¯ãã®ååã§ããããã®èªåãªãã¸ã§ã¯ãã®ã¹ã³ã¼ãããæãå
å´ã®ãããã¯ã®å¤ã«åºãªãå ´åãä¾å¤ãªãã¸ã§ã¯ãã«å¯¾ããã³ãã¼/ã ã¼ããçç¥ãããä¾å¤ãªãã¸ã§ã¯ãä¸ã«ç´æ¥æ§ç¯ãããã¨ã許ããã¦ããã
struct S
{
S() { }
S( S const & ) { }
~S() { }
} ;
int main()
{
try
{
S s ; // æãå
å´ã®ãããã¯ã¹ã³ã¼ãã®å¤ã«åºãªã
throw s ; // ã³ãã¼çç¥ã許ããã¦ãã
} catch ( S & s ) { }
}
-
ãªãã¡ã¬ã³ã¹ã§æç¸ããã¦ããªãã¯ã©ã¹ã®ä¸æãªãã¸ã§ã¯ãããåãCVé修飾ã®åã«ãã³ãã¼/ã ã¼ããããå ´åãã³ãã¼/ã ã¼ãã¯çç¥ãããã³ãã¼/ã ã¼ãå
ã®ãªãã¸ã§ã¯ãã«ãä¸æãªãã¸ã§ã¯ããç´æ¥æ§ç¯ãããã¨ã許ããã¦ããã
struct S
{
S() { }
S( S const & ) { }
~S() { }
} ;
S f()
{
return S() ; // ã³ãã¼çç¥ã許ããã¦ãã
}
int main()
{
S s = f() ; // ã³ãã¼çç¥ã許ããã¦ãã
}
-
ä¾å¤ãã³ãã©ã¼ã®ä¾å¤å®£è¨ããCV修飾å以å¤ã¯åãåã®ãªãã¸ã§ã¯ãããä¾å¤ãªãã¸ã§ã¯ãã¨ãã¦å®£è¨ãã¦ããå ´åãã³ã³ã¹ãã©ã¯ã¿ã¼ã¨ãã¹ãã©ã¯ã¿ã¼å¼ã³åºã以å¤ã«ããã°ã©ã ã®æå³ãå¤ãããªããã°ãã³ãã¼/ã ã¼ãã¯çç¥ãããä¾å¤å®£è¨ã®ä»®å¼æ°ã¯ãä¾å¤ãªãã¸ã§ã¯ããåç
§ãããã¨ã許ããã¦ããã
struct S
{
S() { }
S( S const & ) { }
~S() { }
} ;
int main()
{
try
{
throw S() ;
}
// ã³ãã¼çç¥ã許ããã¦ãã
catch( S s ) { }
}
ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¨ãã¹ãã©ã¯ã¿ã¼å¼ã³åºã以å¤ã«ããã°ã©ã ã®æå³ãå¤ãããªããã¨ããã®ã¯ããã¨ãã°ä¾å¤ãªãã¸ã§ã¯ããå¤æ´ãããããªå ´åã ã
catch( S s )
{
s = S() ; // ä¾å¤ãªãã¸ã§ã¯ããå¤æ´
}
ä¾å¤å®£è¨ã®ãªãã¡ã¬ã³ã¹ã§ã¯ãªãä»®å¼æ°ã®æã示ããªãã¸ã§ã¯ãã«å¤æ´ãå ãã¦ããå
ã®ä¾å¤ãªãã¸ã§ã¯ããå¤æ´ããªãã¨è¦å®ããã¦ããã®ã§ããã®å ´åã¯ãã³ãã¼çç¥ã¯ã§ããªãã
ã³ãã¼çç¥ã®æ¡ä»¶ã¯ãçµã¿åããã£ãå ´åã§ããã³ãã¼çç¥ããããã¨ã許ããã¦ããã
ã³ãã¼çç¥ã§ããæ¡ä»¶ãããããã³ãã¼ããããªãã¸ã§ã¯ããlvalueã®å ´åããªã¼ãã¼ãã¼ã解決ãäºåè¡ããããã¨ããããä¸åç®ã®ãªã¼ãã¼ãã¼ã解決ã¯ããªãã¸ã§ã¯ããrvalueã¨ãã¦ãã³ãã¼ããã³ã³ã¹ãã©ã¯ã¿ã¼ãæ¢ããä¸åç®ã®ãªã¼ãã¼ãã¼ã解決ã失æããããé¸æãããã³ã³ã¹ãã©ã¯ã¿ã¼ã®ç¬¬ä¸å¼æ°ãrvalueãªãã¡ã¬ã³ã¹ã§ã¯ãªãå ´åããªãã¸ã§ã¯ããlvalueã¨ãã¦ãäºåç®ã®ãªã¼ãã¼ãã¼ã解決ãè¡ãããã
ä¸åç®ã®ãªã¼ãã¼ãã¼ã解決ã§ãé¸æãããã³ã³ã¹ãã©ã¯ã¿ã¼ã®ç¬¬ä¸å¼æ°ãrvalueãªãã¡ã¬ã³ã¹ã§ã¯ãªãå ´åã¨ããã®ã¯ããã¨ãã°const修飾ãããlvalueãªãã¡ã¬ã³ã¹ã該å½ããã
ãã®äºåã®ãªã¼ãã¼ãã¼ã解決ã¯ããã¨ãã³ãã¼çç¥ãããªãã¨ãã¦ããå¿
ãè¡ãããããã®è¦å®ã®ç®çã¯ãã³ãã¼çç¥ãè¡ãããªãã£ããªãã°å¼ã³åºãããã³ã³ã¹ãã©ã¯ã¿ã¼ã®ãã¢ã¯ã»ã¹æå®ã調ã¹ãããã§ããã
using宣è¨ã使ã£ã¦æ´¾çã¯ã©ã¹ããåºæ¬ã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ãæå®ãããã¨ã§ãåºæ¬ã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ãæ示çã«ç¶æ¿ã§ãããããã«ãããæ©æ¢°çãªææ¸ãã®ã³ã¼ããçããã¨ãã§ããã
class Base
{
private :
int member ;
public :
Base( int value ) : member(value) { }
} ;
class Derived : Base
{
public :
// Base::Base(int)ãç¶æ¿
using Base::Base ;
} ;
int main()
{
Derived d(0) ; // ç¶æ¿ã³ã³ã¹ãã©ã¯ã¿ã¼ã使ã
}
using宣è¨ã¯é常éããã¢ã¯ã»ã¹æå®ã®å½±é¿ãåãããã¨ã«æ³¨æãããã¨ãæ´¾çã¯ã©ã¹ã«ãã£ã¦ç¶æ¿ãããåºæ¬ã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ãåãä»®å¼æ°ãã¨ããå¼æ°ããã®ã¾ã¾ã¡ã³ãã¼åæååã§åºæ¬ã¯ã©ã¹ã«æ¸¡ããé¢æ°æ¬ä½ã¯ç©ºã§ããã³ã¼ããææ¸ãããå ´åã¨åãããã«åãã
struct Base { Base(int, double) { } } ;
struct Derived : Base
{
// Baseã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã®ç¶æ¿
using Base::Base ;
// 以ä¸ã®ã³ã¼ããææ¸ãããå ´åã¨åç
// Derived( int p1, double p2 )
// : Base( p1, p2 )
// { }
} ;
ãã®ãããªææ¸ãã®ã³ã³ã¹ãã©ã¯ã¿ã¼ããå®éã«ä½¿ãã¨ã¨ã©ã¼ã¨ãªãå ´åãç¶æ¿ã³ã³ã¹ãã©ã¯ã¿ã¼ã®ä½¿ç¨ãã¨ã©ã¼ã¨ãªãã
æ´¾çã¯ã©ã¹ã§åãã·ã°ããã£ã¼ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ãã¦ã¼ã¶ã¼å®ç¾©ããå ´åããã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã®ç¶æ¿ã¯èµ·ãããªãã
struct Base
{
Base( int ) { }
Base( double ) { }
} ;
struct Derived : Base
{
using Base::Base ;
Derived( int value ) : Base(value)
{
// å¦ç
}
}
ãã®å ´åãBase::Base(double)ã¯ç¶æ¿ãããããBase::Base(int)ã¯ç¶æ¿ãããªããã¯ã©ã¹Derivedã§ã¦ã¼ã¶ã¼å®ç¾©ãããã³ã³ã¹ãã©ã¯ã¿ã¼ã使ç¨ãããã
ç¶æ¿ã³ã³ã¹ãã©ã¯ã¿ã¼ã®è©³ç´°ã¯ãããé£ãããã¾ããç¶æ¿ãããåºæ¬ã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ããç¶æ¿ã³ã³ã¹ãã©ã¯ã¿ã¼ã®åè£(candidate set of inherited constructors)ã¨ãã¦åæãããããã®éãã³ã³ã¹ãã©ã¯ã¿ã¼ã«ããã©ã«ãå®å¼æ°ãããå ´åã¯ãããã©ã«ãå®å¼æ°ãçç¥ããã·ã°ããã£ã¼ã®é¢æ°ã追å ãããããã¨ãã°ã以ä¸ã®ãããªã¯ã©ã¹ã®å ´åã
struct A
{
A( int i ) { }
} ;
struct B
{
B( int p1 = 1, int p2 = 2 ) { }
} ;
ã¯ã©ã¹Aã®ç¶æ¿ã³ã³ã¹ãã©ã¯ã¿ã¼ã®åè£ã¯ã以ä¸ã®éãã
A( int )
A( A const & )
A( A && )
ã¯ã©ã¹Bã®ç¶æ¿ã³ã³ã¹ãã©ã¯ã¿ã¼ã®åè£ã¯ã以ä¸ã®éãã
B( ) // ããã©ã«ãå®å¼æ°ã®çç¥å½¢
B( int = 1 ) // ããã©ã«ãå®å¼æ°ã®çç¥å½¢
B( int = 1, int = 2 )
B( B const & )
B( B && )
ãã¦ããã®ç¶æ¿ã³ã³ã¹ãã©ã¯ã¿ã¼ã®åè£ãããå¼æ°ãåããªãã³ã³ã¹ãã©ã¯ã¿ã¼ï¼ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ï¼ãå¼æ°ãã²ã¨ã¤ã ãåãã³ãã¼/ã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ãé¤ãã³ã³ã¹ãã©ã¯ã¿ã¼ãç¶æ¿ã³ã³ã¹ãã©ã¯ã¿ã¼ã¨ãªãããããã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ãæ´¾çã¯ã©ã¹å´ã§æé»ã«å®£è¨ããããã®ã ããã ããã ããæ´¾çã¯ã©ã¹ã§åãã·ã°ããã£ã¼ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ãã¦ã¼ã¶ã¼å®ç¾©ããã¦ããå ´åã¯ãç¶æ¿ãããªãã
ããã¤ãä¾ã示ãã
struct Base
{
Base( int ) { }
} ;
struct Derived : Base
{
using Base::Base ;
} ;
ãã®å ´åãã¯ã©ã¹Derivedã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ã以ä¸ã®ããã«ãªãã
Derived( ) // ç¶æ¿ã³ã³ã¹ãã©ã¯ã¿ã¼ã§ã¯ãªãã使ãã¨ã¨ã©ã¼ã«ãªã
Derived( int ) // ã¯ã©ã¹Bããç¶æ¿ãããã³ã³ã¹ãã©ã¯ã¿ã¼
Derived( Derived const & ) // ç¶æ¿ã³ã³ã¹ãã©ã¯ã¿ã¼ã§ã¯ãªã
Derived( Derived && ) // ç¶æ¿ã³ã³ã¹ãã©ã¯ã¿ã¼ã§ã¯ãªã
ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãã³ãã¼/ã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ç¶æ¿ãããªãã®ã§ãé常éãã®æåã«ãªãããã®å ´åãã¯ã©ã¹Baseã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯æé»ã«å®£è¨ããã¦ããªãããã¦ã¼ã¶ã¼å®ç¾©ãããã¦ããªãããã使ãã¨ã¨ã©ã¼ã«ãªãã
struct A
{
A( int ) { }
} ;
struct B
{
B( int ) { }
} ;
struct C : A, B
{
using A::A ;
using B::B ;
// ã¨ã©ã¼ã宣è¨ã®éè¤
} ;
struct D : A, B
{
using A::A ;
using B::B ;
D( int x ) : A(x), B(x) { } // OKãã¦ã¼ã¶ã¼å®ç¾©ãåªå
}
ã¯ã©ã¹Cã§ã¯ãC(int)ãéè¤ãã¦å®£è¨ãã¦ãã¾ãã®ã§ãã¨ã©ã¼ã¨ãªããã¯ã©ã¹Dã§ã¯ãã¦ã¼ã¶ã¼å®ç¾©ãããããã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ã®ç¶æ¿ã¯èµ·ãããªãããã£ã¨ãããã®å ´åãusing宣è¨ã使ã£ã¦ã³ã³ã¹ãã©ã¯ã¿ã¼ãç¶æ¿ããæå³ããªãã
é¢æ°ã¨é¢æ°ãã³ãã¬ã¼ãã¯ãç°ãªã宣è¨ã§ããã°ãåä¸ã¹ã³ã¼ãå
ã§ããåãååã使ããã¨ãã§ããããããããªã¼ãã¼ãã¼ã(overload)ã¨ããããªã¼ãã¼ãã¼ããããååãé¢æ°å¼ã³åºãã§ä½¿ãããå ´åããªã¼ãã¼ãã¼ã解決(overload resolution)ãè¡ãããæãæé©ãªå®£è¨ãé¸ã°ããã
void name( int ) ;
void name( double ) ;
int main()
{
name( 0 ) ; // name(int)
name( 0.0 ) ; // name(double)
}
ããã«ãããå¼æ°ãéãã ãã§æ¬è³ªçã«ã¯åãé¢æ°ç¾¤ã«ãããããå¥åãä»ããªãã¦ããããªãã
ã·ã°ããã£ãç°ãªã£ã¦ããã°ãã©ã®ãããªé¢æ°ããããã¯é¢æ°ãã³ãã¬ã¼ãã§ããªã¼ãã¼ãã¼ãã§ããããã§ã¯ãªãã以ä¸ã¯ããªã¼ãã¼ãã¼ãã§ã¯èæ
®ãããªãã·ã°ããã£ä¸ã®éãã§ããã
-
æ»ãå¤ã®å
int f( int ) { return 0 ; }
double f( int ) { return 0.0 ; } // ã¨ã©ã¼ããªã¼ãã¼ãã¼ãã§ããªã
-
ã¡ã³ãã¼é¢æ°ã¨ã¡ã³ãã¼é¢æ°ãã³ãã¬ã¼ãã«ããã¦ãstaticã¨éstaticã®éã
struct Foo
{
void f() ;
static void f() ; // ã¨ã©ã¼
} ;
-
ã¡ã³ãã¼é¢æ°ã¨ã¡ã³ãã¼é¢æ°ãã³ãã¬ã¼ãã«ããã¦ããªãã¡ã¬ã³ã¹ä¿®é£¾åã®æç¡ãæ··å¨ãã¦ããå ´å
ã¡ã³ãã¼é¢æ°ã®æé»ã®ãªãã¸ã§ã¯ãä»®å¼æ°ã®ãªãã¡ã¬ã³ã¹ã«ãããªã¼ãã¼ãã¼ããè¡ãããå ´åã¯ãlvalueãªãã¡ã¬ã³ã¹ã§ãããªãã¡ã¬ã³ã¹ä¿®é£¾åãçç¥ãããã¨ã¯ã§ããªãã
struct Foo
{
void f() ; // ãªãã¡ã¬ã³ã¹ä¿®é£¾åã®çç¥ãæé»ã«lvalueãªãã¡ã¬ã³ã¹
void f() && ; // ã¨ã©ã¼ãä»ã®å®£è¨ã§ãªãã¡ã¬ã³ã¹ä¿®é£¾åãçç¥ããã¦ãã
void g() & ; // OK
void g() && ; // OK
} ;
-
ä»®å¼æ°ã®åããåãåãæãç°ãªãtypedefåã®å ´å
using Int = int ;
void f( int ) ;
void f( Int ) ; // å宣è¨
typedefåã¯åãªãå¥åã§ãã£ã¦ãç°ãªãåã§ã¯ãªãã®ã§ãã·ã°ããã£ã¯ããªãã«ãªãã
-
ä»®å¼æ°ã®åã®éããã*ã[]ã§ããå ´å
é¢æ°ã®åã§èª¬æããããã«ãä»®å¼æ°ã®ãã¤ã³ã¿ã¼ã¨é
åã®ã·ã°ããã£ã¯åãã§ããããã ãã2ã¤ç®ä»¥éã®é
åã¯èæ
®ãããã®ã§æ³¨æã
void f( int * ) ;
void f( int [] ) ; // å宣è¨ãvoid f(int *)ã¨åã
void f( int [2] ) ; // å宣è¨ãvoid f(int *)ã¨åã
void f( int [][2] ) ; // ãªã¼ãã¼ãã¼ããã·ã°ããã£ã¯void f(int(*)[2])
-
ä»®å¼æ°ãé¢æ°åããåãé¢æ°åã¸ã®ãã¤ã³ã¿ã¼ã§ããå ´å
é¢æ°ã®åã§èª¬æããããã«ãä»®å¼æ°ã¨ãã¦ã®é¢æ°åã¯åãé¢æ°åã¸ã®ãã¤ã³ã¿ã¼åã«å¤æãããã
void f( void(*)() ) ;
void f( void () ) ; // å宣è¨
void f( void g() ) ; // å宣è¨
ãããã¯ãªã¼ãã¼ãã¼ãã§ã¯ãªãã
-
ä»®å¼æ°ã®ãããã¬ãã«ã®CV修飾åã®æç¡
é¢æ°ã®åã§èª¬æããããã«ãä»®å¼æ°ã®ãããã¬ãã«ã®CV修飾åã¯ç¡è¦ãããããããã¬ãã«ä»¥å¤ã®CV修飾åã¯å¥ã®åã¨ã¿ãªãããã®ã§ããªã¼ãã¼ãã¼ãã¨ãªãã
void f( int * ) ;
void f( int * const ) ; // å宣è¨
void f( int * volatile ) ; // å宣è¨
void f( int * const volatile ) ; // å宣è¨
void f( int const * ) ; // ãªã¼ãã¼ãã¼ã
void f( int volatile * ) ; // ãªã¼ãã¼ãã¼ã
void f( int const volatile * ) ; // ãªã¼ãã¼ãã¼ã
-
ããã©ã«ãå®å¼æ°ã®éã
ããã©ã«ãå®å¼æ°ã®éãã¯ããªã¼ãã¼ãã¼ãã¨ã¯ã¿ãªãããªãã
void f( int, int ) ;
void f( int, int = 0 ) ; // å宣è¨
void f( int = 0, int = 0 ) ; // å宣è¨
ãªã¼ãã¼ãã¼ã解決ã¯ãåå解決ã«ãã£ã¦è¤æ°ã®å®£è¨ãåæãããå ´åã«è¡ããããå
å´ã®ã¹ã³ã¼ãã«ãã£ã¦ååãé ããã¦ããå ´åã¯ããªã¼ãã¼ãã¼ã解決ã¯è¡ãããªãã
ãã¨ãã°ãæ´¾çã¯ã©ã¹ã§åºæ¬ã¯ã©ã¹ã®ã¡ã³ãã¼é¢æ°åã¨ååã®ãã®ãããå ´åããã®ã¡ã³ãã¼é¢æ°ã¯åºæ¬ã¯ã©ã¹ã®ã¡ã³ãã¼é¢æ°ã®ååãé ãã
struct Base
{
void f( int ) { }
} ;
struct Derived : Base
{
void f( double ) { } // Base::f(int)ãé ã
} ;
int main()
{
Derived d ;
d.f( 0 ) ; // Derived::f(double)ãå¼ã°ãã
}
ä¼¼ããããªä¾ã«ãé¢æ°ã®ãã¼ã«ã«å®£è¨ãããã
void f( int ) { }
void f( double ) { }
int main()
{
f( 0 ) ; // f(int)ãå¼ã³åºã
void f( double ) ; // f(int)ãé ã
f( 0 ) ; // f(double)ãå¼ã³åºã
}
ãªã¼ãã¼ãã¼ããããã¡ã³ãã¼é¢æ°ã¯ãããããå¥ã
ã®ã¢ã¯ã»ã¹æå®ãæã¤ãã¨ãã§ãããã¢ã¯ã»ã¹æå®ã¯åå解決ã«ã¯å½±é¿ããªãã®ã§ããªã¼ãã¼ãã¼ã解決ã¯è¡ãããã
class X
{
private :
void f( int ) { }
public :
void f( double ) { }
} ;
int main()
{
X x ;
x.f( 0 ) ; // ã¨ã©ã¼ãX::f(int)ã¯privateã¡ã³ãã¼
}
ãã®ä¾ã§ã¯ããªã¼ãã¼ãã¼ã解決ã«ãã£ã¦ãX::f(int)ãé¸ã°ããããããã¯privateã¡ã³ãã¼ãªã®ã§ãXã®friendã§ã¯ãªãmainé¢æ°ããã¯å¼ã³åºããªãããã£ã¦ã¨ã©ã¼ã«ãªãã
ãªã¼ãã¼ãã¼ããããé¢æ°ãå¼ã³åºãéã«ãå®å¼æ°ããå¤æãã¦ãæããµããããé¢æ°ãé¸ã°ããããããããªã¼ãã¼ãã¼ã解決(Overload resolution)ã¨å¼ã¶ããªã¼ãã¼ãã¼ã解決ã®ã«ã¼ã«ã¯é常ã«è¤éã§ãããåç´ã«å®å¼æ°ã¨ä»®å¼æ°ã®åãä¸è´ããã ããªãã¾ã 話ã¯ç°¡åã ã
void f( int ) { }
void f( double ) { }
int main()
{
f( 0 ) ; // f(int)ãå¼ã°ãã
f( 0.0 ) ; // f(double)ãå¼ã°ãã
}
ãã®çµæã«ã¯ãçåã¯ãªããå®å¼æ°ã¨ä»®å¼æ°ã®åãä¸è´ãã¦ããããã ããããããããå®å¼æ°ã®åã¨ä»®å¼æ°ã®åãä¸è´ãã¦ããªãããæé»ã®åå¤æã«ãã£ã¦ä»®å¼æ°ã®åã«å¤æå¯è½ãªå ´åãåé¡ã¯é常ã«ããããããªãã
void f( int ) { }
void f( double ) { }
int main()
{
short a = 0 ;
f( a ) ; // f(int)ãå¼ã¶
float b = 0.0f ;
f( b ) ; // f(double)ãå¼ã¶
}
ãã®çµæãã妥å½ãªãã®ã§ãããshortã¯æ´æ°åãªã®ã§ãdoubleããã¯intãåªå
ãã¦æ¬²ãããfloatã¯ãæµ®åå°æ°ç¹æ°åãªã®ã§ãdoubleãåªå
ãã¦æ¬²ããã
ã§ã¯ã以ä¸ã®ãããªå ´åã¯ã©ãã ãããã
void f( int ) { }
void f( long long ) { }
int main()
{
long a = 0l ;
f( a ) ; // ææ§
short b = 0 ;
f( b ) ; // f(int)ãå¼ã³åºã
}
ãã®çµæã¯ãå°ãæå¤ã ãæ¯ã¹ãã¹ãåã¯ãintã¨long long intã§ãããlongåã渡ãã¨ææ§ã«ãªããããããshortåã渡ãã¨ããªãã¨intåãé¸ã°ããããã¡ãã¯ææ§ã«ãªããªããããã¯ãshortåããintåã¸ã®åå¤æã«æ´æ°ã®ããã¢ã¼ã·ã§ã³ã使ããã¦ããããã§ããã
ã§ã¯ãã¦ã¼ã¶ã¼å®ç¾©ã®åå¤æãé¢ä¿ããå ´åã¯ã©ãã ãããã
void f( int ) { }
class X
{
public :
X() = default ;
X( double ) { } // ã¦ã¼ã¶ã¼å®ç¾©ã®åå¤æ
} ;
void f( X ) { }
int main()
{
f( 0.0 ) ; // f(int)ãå¼ã¶
}
ãã®å ´åãã¦ã¼ã¶ã¼å®ç¾©ã®åå¤æãããè¨èªå´ã«çµã¿è¾¼ã¾ãããæ¨æºåå¤æãåªå
ãã¦ããã
ã§ã¯ãå¼æ°ãè¤æ°ããå ´åã¯ã©ããªãã®ããé¢æ°ãã³ãã¬ã¼ãã®å ´åã¯ã©ããªãã®ããçåã¯å°½ããªãããªã¼ãã¼ãã¼ã解決ã®ã«ã¼ã«ã¯é常ã«è¤éã§ãããããã¯ãã§ããã ããªã¼ãã¼ãã¼ã解決ã®æåãã人éã«ã¨ã£ã¦èªç¶ã«ãã詳細ãç¥ããªãã¦ãåé¡ããªãããã«è¨è¨ããçµæã§ããããã®ä»£åã¨ãã¦ããªã¼ãã¼ãã¼ã解決ã®è©³ç´°ã¯é常ã«è¤éã«ãªããå®è£
ã«ãæéããããããã«ãªã£ãã
ãªã¼ãã¼ãã¼ã解決ã®æé ããç°¡æ½ã«ã¾ã¨ããã¨ã以ä¸ã®ããã«ãªãã
- ååæ¢ç´¢ã«ãã£ã¦è¦ã¤ããååã®é¢æ°ããã¹ã¦ãåè£é¢æ°(Candidate functions)ã¨ãã¦åæãã
- åè£é¢æ°ãããå®éã«å¼ã³åºããã¨ãå¯è½ãªé¢æ°ããé©åé¢æ°(Viable functions)ã«çµã
- å®å¼æ°ããä»®å¼æ°ã¸ã®æé»ã®åå¤æãèæ
®ãã¦ãæé©ãªé¢æ°(Best viable function)ã決å®ãã
ä¾ãã°ã以ä¸ã®ãããªãªã¼ãã¼ãã¼ã解決ã®å ´åã
void f() { }
void f( int ) { }
void f( int, int ) { }
void f( double ) { }
void g( int ) { }
int main()
{
f( 0 ) ; // ãªã¼ãã¼ãã¼ã解決ãå¿
è¦
}
åè£é¢æ°ã«ã¯ãf(), f(int), f(int,int), f(double)ãåæããããé©åé¢æ°ã«ã¯ãf(int), f(double)ãé¸ã°ããããããæ¯è¼ããã¨ãf(int)ãåä¸è´ã§æé©é¢æ°ã¨ãªãã
æ¬æ¸ã«ããããªã¼ãã¼ãã¼ã解決ã®è§£èª¬ã¯ãç´°é¨ãããªãçç¥ãã¦ããã
åè£é¢æ°(Candidate functions)ã¯ãæ£ç¢ºã«è¨ãã°ãåè£é¢æ°ç¾¤ã¨ã§ã訳ãããã¹ãã§ããããåè£é¢æ°ã¨ã¯ããã®ååã®éãããªã¼ãã¼ãã¼ã解決ã®éã«å¼ã³åºãã®åªå
é ä½ãèæ
®ãããé¢æ°ã®ãã¨ã§ãããåè£é¢æ°ã«é¸ã°ããªããã°ãå¼ã³åºããããã¨ã¯ãªããããååã«å¯¾ãã¦ãªã¼ãã¼ãã¼ã解決ãå¿
è¦ãªå ´åã«ãã¾ãæåã«è¡ãããã®ããåè£é¢æ°ã®åæã§ãããåè£é¢æ°ã¯ãé常éãã«ååæ¢ç´¢ããããªã£ã¦è¦ã¤ããé¢æ°ãã¹ã¦ã§ãããããã«ã¯ãå®éã«ã¯å¼ã³åºããã¨ã®ã§ããªãé¢æ°ãå«ãããªã¼ãã¼ãã¼ã解決ã®éã«èæ
®ããã®ã¯ããã®åè£é¢æ°ã ãã§ããããã®ä»ã®é¢æ°ã¯èæ
®ããªãã
void f() { }
void f( int ) { }
void g() { }
int main()
{
f( 0 ) ; // åè£é¢æ°ã®åæãå¿
è¦
}
ããã§ã®åè£é¢æ°ã¨ã¯ãf()ã¨f(int)ã§ãããf()ã¯ãå®éã«å¼ã³åºããã¨ãã§ããªãããåè£é¢æ°ã¨ãã¦åæãããããã®å ´åãg()ã¯åè£é¢æ°ã§ã¯ãªãã
ãªã¼ãã¼ãã¼ã解決ã®éã«ä½¿ãããååæ¢ç´¢ã¯ãé常ã®ååæ¢ç´¢ã¨ä½ãå¤ãããªãã¨ãããã¨ã«æ³¨æããªããã°ãªããªããä¾ãã°ãååãé ããã¦ããå ´åã¯ãçºè¦ãããªãã
void f( int ) { }
void f( double ) { }
int main()
{
f( 0 ) ; // #1 f(int)
void f( double ) ; // å宣è¨ãf(int)ãé ã
f( 0 ) ; // #2 f(double)
}
#1ã§ã¯ãf(int)ãååæ¢ç´¢ã§è¦ã¤ããã®ã§ããªã¼ãã¼ãã¼ã解決ã«ãã£ã¦ãf(int)ãæé©é¢æ°ã«é¸ã°ããã#2ã§ã¯ãf(int)ã¯é ããã¦ããã®ã§ãååæ¢ç´¢ã§ã¯è¦ã¤ãããªãããã®ãããf(int)ã¯åè£é¢æ°ã«ã¯ãªããªããçµæã¨ãã¦ãf(double)ãæé©é¢æ°ã«é¸ã°ããã
é¢æ°ã®ãã¼ã«ã«å®£è¨ã¯ã¾ã使ãããªãããæ´¾çã¯ã©ã¹ã®ã¡ã³ãã¼é¢æ°ã®å®£è¨ã«ãã£ã¦ãåºæ¬ã¯ã©ã¹ã®ã¡ã³ãã¼é¢æ°ãé ããããã¨ã¯ããããã
struct Base
{
void f( int ) { }
void f( long ) { }
} ;
struct Derived : Base
{
void f( double ) { } // Baseã¯ã©ã¹ã®ååfãé ã
void g()
{
f( 0 ) ; // Derived::f(double)
}
} ;
ãã®ä¾ã§ã¯ãDerived::f(double)ããBaseã®ã¡ã³ãã¼é¢æ°fãé ãã¦ãã¾ãã®ã§ãåè£é¢æ°ã«ã¯Derived::f(double)ããåæãããªãã
åè£é¢æ°ãã¡ã³ãã¼é¢æ°ã§ããå ´åãã³ã¼ãä¸ã«ã¯ç¾ããªãä»®å¼æ°ã¨ãã¦ãã¯ã©ã¹ã®ãªãã¸ã§ã¯ããåããããããæé»ã®ãªãã¸ã§ã¯ãä»®å¼æ°(implicit object parameter)ã¨å¼ã¶ãããã¯ããªã¼ãã¼ãã¼ã解決ã®éã«èæ
®ããããæé»ã®ãªãã¸ã§ã¯ãä»®å¼æ°ã¯ããªã¼ãã¼ãã¼ã解決ã«ããã¦ã¯ãé¢æ°ã®ç¬¬ä¸å¼æ°ã ã¨ã¿ãªããããæé»ã®ãªãã¸ã§ã¯ãä»®å¼æ°ã®åã¯ãã¾ããã¯ã©ã¹ã®åXã«CV修飾åãã¤ããããã«ã
ãªãã¡ã¬ã³ã¹ä¿®é£¾åããªãå ´åããããã¯ããªãã¡ã¬ã³ã¹ä¿®é£¾åã&ã®å ´åãXï¼å ´åã«ãã£ã¦CV修飾åï¼ã¸ã®lvalueãªãã¡ã¬ã³ã¹ã
struct X
{
// ã³ã¡ã³ãã¯æé»ã®ãªãã¸ã§ã¯ãä»®å¼æ°ã®å
void f() & ; // X &
void f() const & ; // X const &
void f() volatile & ; // X volatile &
void f() const volatile & ; // X const volatile &
void g() ; // X &
} ;
ãªãã¡ã¬ã³ã¹ä¿®é£¾åã&&ã®å ´åãX(å ´åã«ãã£ã¦CV修飾å)ã¸ã®rvalueãªãã¡ã¬ã³ã¹ã
struct X
{
// ã³ã¡ã³ãã¯æé»ã®ãªãã¸ã§ã¯ãä»®å¼æ°ã®å
void f() && ; // X &&
void f() const && ; // X const &&
void f() volatile && ; // X volatile &&
void f() const volatile && ; // X const volatile &&
} ;
ã¨ãªããä¾ãã°ã以ä¸ã®ããã«ãªã¼ãã¼ãã¼ã解決ã«å½±é¿ããã
struct X
{
void f() & ; // #1 æé»ã®ãªãã¸ã§ã¯ãä»®å¼æ°ã®åã¯ãX &
void f() const & ; // #2 æé»ã®ãªãã¸ã§ã¯ãä»®å¼æ°ã®åã¯ãX const &
void f() && ; // #3 æé»ã®ãªãã¸ã§ã¯ãä»®å¼æ°ã®åã¯ãX &&
} ;
int main()
{
X x ;
x.f() ; // #1
X const cx ;
cx.f() ; // #2
static_cast<X &&>(x).f() ; // #3
}
åè£é¢æ°ã«ã¯ãã¡ã³ãã¼é¢æ°ã¨éã¡ã³ãã¼é¢æ°ã®ä¸¡æ¹ãå«ããã¨ãããã
struct X
{
X operator + ( int ) const
{ return X() ; }
} ;
X operator + ( X const &, double )
{ return X() ; }
int main()
{
X x ;
x + 0 ; // X::operator+(int)
x + 0.0 ; // operator+(X const &, double)
}
ãã®å ´åãåè£é¢æ°ã«ã¯ãã¡ã³ãã¼é¢æ°ã§ããX::operator +ã¨ãéã¡ã³ãã¼é¢æ°ã§ããoperator+ã®ä¸¡æ¹ãå«ã¾ãããåè£é¢æ°ã«åæãããã®ã§ãå½ç¶ããªã¼ãã¼ãã¼ã解決ã§æé©é¢æ°ã決å®ãããã
ãã³ãã¬ã¼ãã®å®å¼æ°æ¨å®ã¯ãåå解決ã®éã«è¡ãããããã®ãããåè£é¢æ°ã¨ãã¦é¢æ°ãã³ãã¬ã¼ãã®ã¤ã³ã¹ã¿ã³ã¹ãåæãããæç¹ã§ããã³ãã¬ã¼ãå®å¼æ°ã¯æ±ºå®ããã¦ããã
ãªã¼ãã¼ãã¼ã解決ãè¡ãããæèã«ã¯ãããã¤ã種é¡ããããããã«ãã£ã¦ãåè£é¢æ°ã®é¸ã³æ¹ãéã£ã¦ããã
æãåãããããé¢æ°å¼ã³åºãã¯ãé¢æ°å¼ã³åºãã®ææ³ã«ãããã®ã ãããããããä¸å£ã«é¢æ°å¼ã³åºãã®ææ³ã¨ãã£ã¦ããå¾®å¦ã«éãããããåãªãé¢æ°åã«å¯¾ããé¢æ°å¼ã³åºãå¼ã®é©ç¨ãããã°ãã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã«.ã->ã使ã£ãå¼ã«å¯¾ããé¢æ°å¼ã³åºããã¤ã¾ãã¡ã³ãã¼é¢æ°ã®å¼ã³åºãããã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã«å¯¾ããé¢æ°å¼ã³åºãå¼ãã¤ã¾ãoperator ()ã®ãªã¼ãã¼ãã¼ããå¼ã³åºããã®ãããã
struct X
{
void f( int ) { }
void f( double ) { }
void operator () ( int ) { }
void operator () ( double ) { }
} ;
int main()
{
X x ;
x.f( 0 ) ; // ãªã¼ãã¼ãã¼ã解決ãå¿
è¦
x( 0 ) ; // ãªã¼ãã¼ãã¼ã解決ãå¿
è¦
}
ãªã¼ãã¼ãã¼ã解決ã¯ãé¢æ°ã¸ã®ãã¤ã³ã¿ã¼ããªãã¡ã¬ã³ã¹ãçµç±ããéæ¥çãªå¼ã³åºãã®éã«ã¯ãè¡ãããªãã
void f( int ) { }
void f( double ) { }
int main()
{
void (* p)( int ) = &f ;
p( 0.0 ) ; // f(int)
}
ãã®é
ã¯ããªã¼ãã¼ãã¼ããããæ¼ç®åãåè£é¢æ°ã¨ãã¦è¦ã¤ããéã®è©³ç´°ã§ãããæ¼ç®åã®ãªã¼ãã¼ãã¼ãã®å®£è¨æ¹æ³ã«ã¤ãã¦ã¯ããªã¼ãã¼ãã¼ããããæ¼ç®åãåç
§ã
æ¼ç®åã使ã£ãå ´åã«ãããªã¼ãã¼ãã¼ã解決ãå¿
è¦ã«ãªãããã ããæ¼ç®åã«ãªã¼ãã¼ãã¼ã解決ãè¡ãããå ´åããªãã©ã³ãã«ã¯ã©ã¹ãenumãé¢ãã£ã¦ããªããã°ãªããªãããªãã©ã³ããåºæ¬åã ãã§ããã°ãçµã¿è¾¼ã¿ã®æ¼ç®åã使ãããã
// ã¨ã©ã¼ããªãã©ã³ãããã¹ã¦åºæ¬å
int operator + (int, int) { return 0 ; }
æ¼ç®åã®ãªã¼ãã¼ãã¼ãã¯ãã¡ã³ãã¼é¢æ°ã¨ãã¦ãªã¼ãã¼ãã¼ãããæ¹æ³ã¨ãéã¡ã³ãã¼é¢æ°ã¨ãã¦ãªã¼ãã¼ãã¼ãããæ¹æ³ãããããã§ã«è¿°ã¹ãããã«ãåè£é¢æ°ã«ã¯ãã©ã¡ããåæãããã
æ¼ç®åã®ãªã¼ãã¼ãã¼ãé¢æ°ã¯ãæ¼ç®åãä»®ã«@ã¨ç½®ãã¨ã以ä¸ã®è¡¨ã®ããã«å¼ã°ããã
ç¨®é¡ |
å¼ |
ã¡ã³ãã¼é¢æ°ã¨ãã¦å¼ã³åºãå ´å |
éã¡ã³ãã¼é¢æ°ã¨ãã¦å¼ã³åºãå ´å |
åé
åç½® |
@a |
(a).operator@ ( ) |
operator@ (a) |
åé
å¾ç½® |
a@ |
(a).operator@ (0) |
operator@ (a, 0) |
äºé
|
a@b |
(a).operator@ (b) |
operator@ (a, b) |
代å
¥ |
a=b |
(a).operator= (b) |
æ·»å |
a[b] |
(a).operator[](b) |
ã¯ã©ã¹ã¡ã³ãã¼ã¢ã¯ã»ã¹ |
a-> |
(a).operator-> ( ) |
代å
¥ãæ·»åãã¯ã©ã¹ã¡ã³ãã¼ã¢ã¯ã»ã¹ã®æ¼ç®åã¯ãã¡ã³ãã¼é¢æ°ã¨ãã¦å®£è¨ããªããã°ãªããªãã®ã§ãéã¡ã³ãã¼é¢æ°ã¯åå¨ããªãã
ã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã®ç´æ¥åæåã®å ´åããã®ã¯ã©ã¹ããã³ã³ã¹ãã©ã¯ã¿ã¼ãåè£é¢æ°ã¨ãã¦åæããããªã¼ãã¼ãã¼ã解決ãè¡ãããã
struct X
{
X( int ) { }
X( double ) { }
} ;
int main()
{
X a( 0 ) ; // ãªã¼ãã¼ãã¼ã解決ãè¡ããã
X b( 0.0 ) ; // ãªã¼ãã¼ãã¼ã解決ãè¡ããã
}
ã¯ã©ã¹ã®ã³ãã¼åæåã«ãããã¦ã¼ã¶ã¼å®ç¾©åå¤æã«ã¯ããªã¼ãã¼ãã¼ã解決ãè¡ããããã¦ã¼ã¶ã¼å®ç¾©åå¤æã«ã¯ãå¤æã³ã³ã¹ãã©ã¯ã¿ã¼ã¨å¤æé¢æ°ããããããã¯ã両æ¹ã¨ããåè£é¢æ°ã¨ãã¦åæãããã
struct Destination ;
extern Destination obj ;
struct Source
{
operator Destination &() { return obj ; }
} ;
struct Destination
{
Destination() { }
Destination( Source const & ) { }
} ;
Destination obj ;
int main()
{
Source s ;
Destination d ;
d = s ; // ãªã¼ãã¼ãã¼ã解決ãSource::operator Destination &()
Source const cs ;
d = cs ; // ãªã¼ãã¼ãã¼ã解決ãDestination::Destination( Source const & )
}
ãã®ä¾ã§ã¯ãå¤æã³ã³ã¹ãã©ã¯ã¿ã¼ã¨å¤æé¢æ°ã®ä¸¡æ¹ãåè£é¢æ°ã¨ãã¦åæãããããã®ä¾ã§ãããå¤æã³ã³ã¹ãã©ã¯ã¿ã¼ã®ä»®å¼æ°ããSource &ãªãã°ããªã¼ãã¼ãã¼ã解決ã¯ææ§ã«ãªãã
ãã ããexplicitå¤æã³ã³ã¹ãã©ã¯ã¿ã¼ã¨explicitå¤æé¢æ°ã¯ãç´æ¥åæåããæ示çãªãã£ã¹ãã使ãããéã«ããåè£é¢æ°ã«ãªããªãã
struct X
{
X() { }
explicit X( int ) { }
explicit operator int() { return 0 ; }
} ;
int main()
{
X x ;
int a( x ) ; // OK
int b = x ; // ã¨ã©ã¼
X c( 0 ) ; // OK
X d = 0 ; // ã¨ã©ã¼
}
ãã®å ´åã®å®å¼æ°ãªã¹ãã«ã¯ãåæåå¼ã使ããããå¤æã³ã³ã¹ãã©ã¯ã¿ã¼ã®å ´åã¯ã第ä¸ä»®å¼æ°ã¨æ¯è¼ãããå¤æé¢æ°ã®å ´åã¯ãã¯ã©ã¹ã®é ããªãã¸ã§ã¯ãä»®å¼æ°ã¨æ¯è¼ãããã
// å¤æã³ã³ã¹ãã©ã¯ã¿ã¼ã®ä¾
struct A { } ;
struct X
{
// åè£é¢æ°
X( A & ) { }
X( A const & ) { }
} ;
int main()
{
A a ;
X x1 = a ; // ãªã¼ãã¼ãã¼ã解決ãA::A(A&)
A const ca ;
X x2 = ca ; // ãªã¼ãã¼ãã¼ã解決ãA::A(A const &)
}
ãã®ä¾ã§ã¯ãå®å¼æ°ã¨ãã¦aãcaã使ãããã¯ã©ã¹Xã®å¤æã³ã³ã¹ãã©ã¯ã¿ã¼ã®ç¬¬ä¸ä»®å¼æ°ã¨æ¯è¼ãããã
// å¤æé¢æ°ã®ä¾
struct A { } ;
struct X
{
// åè£é¢æ°
operator A() & { return A() ; }
operator A() const & { return A() ; }
operator A() && { return A() ; }
} ;
int main()
{
X x ;
// ãªã¼ãã¼ãã¼ã解決ãX::operator A() &
// å®å¼æ°ã¯lvalueã®X
A a1 = x ;
X const cx ;
// ãªã¼ãã¼ãã¼ã解決ãX::operator A() const &
// å®å¼æ°ã¯constãªlvalue
A a2 = cx ;
// ãªã¼ãã¼ãã¼ã解決ãX::operator A() &&
// å®å¼æ°ã¯xvalue
A a3 = static_cast<X &&>(x) ;
}
ãã®ä¾ã§ã¯ãã¯ã©ã¹Xã®ãªãã¸ã§ã¯ããå®å¼æ°ã¨ãã¦ãå¤æé¢æ°ã®ã¯ã©ã¹ã®é ããªãã¸ã§ã¯ãä»®å¼æ°ã¨ãã¦æ¯è¼ãããããã¨ãã°ãA a1 = x ; ã®å ´åãå®å¼æ°ã¯éconstãªlvalueãªã®ã§ããªã¼ãã¼ãã¼ã解決ã«ãããX::operator A() &ãé¸ã°ããã
ãã®ä»ã®å¤æã³ã³ã¹ãã©ã¯ã¿ã¼ã¨å¤æé¢æ°ã«å¯¾ãã¦ãããªã¼ãã¼ãã¼ã解決ã§æ¯è¼ããå®å¼æ°ã¨ä»®å¼æ°ã¯ããã«åãã
ã¯ã©ã¹ã§ã¯ãªããªãã¸ã§ã¯ãããã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã®åæåå¼ã§åæåããéãã¯ã©ã¹ã®å¤æé¢æ°ãåè£é¢æ°ã¨ãã¦åæããããªã¼ãã¼ãã¼ã解決ãè¡ããããå®å¼æ°ãªã¹ãã«ã¯ãåæåå¼ãã²ã¨ã¤ã®å®å¼æ°ã¨ãã¦æ¸¡ãããã
struct X
{
operator int() { return 0 ; }
operator long() { return 0L ; }
operator double() { return 0.0 ; }
} ;
int main()
{
X x ;
int i = x ; // ãªã¼ãã¼ãã¼ã解決ãè¡ããã
}
ãã®ä¾ã§ã¯ãåè£é¢æ°ã«ãX::operator intãX::operator longãX::operator doubleãåæããããªã¼ãã¼ãã¼ã解決ã«ãã£ã¦X::operator intãé¸ã°ããã
ãªãã¡ã¬ã³ã¹ãåæåããã¨ããåæåå¼ã«å¤æé¢æ°ãé©ç¨ãã¦ããã®çµæãæç¸ã§ããããã®ã¨ããã¯ã©ã¹ã®å¤æé¢æ°ãåè£é¢æ°ã¨ãã¦åæããããªã¼ãã¼ãã¼ã解決ãè¡ãããã
struct X
{
operator int() { return 0 ; }
operator short() { return 0 ; }
} ;
int main()
{
X x ;
int && ref = x ; // ãªã¼ãã¼ãã¼ã解決ãX::operator int()
}
ã¢ã°ãªã²ã¼ãã§ã¯ãªãã¯ã©ã¹ããªã¹ãåæåã«ãã£ã¦åæåãããã¨ãããªã¼ãã¼ãã¼ã解決ã«ãã£ã¦ã³ã³ã¹ãã©ã¯ã¿ã¼ãé¸æãããã
ãã®éã®åè£é¢æ°ã®åæã¯ãäºæ®µéã«åããã¦ããã
ã¾ãä¸æ®µéã«ãã¯ã©ã¹ã®åæåãªã¹ãã³ã³ã¹ãã©ã¯ã¿ã¼ãåè£é¢æ°ã¨ãã¦åæããããªã¼ãã¼ãã¼ã解決ãè¡ããããå®å¼æ°ãªã¹ãã«ã¯ãåæåãªã¹ããå¯ä¸ã®å®å¼æ°ã¨ãã¦ãstd::initializer_list<T>ã®å½¢ã§ãä¸ããããã
struct X
{
// åæåãªã¹ãã³ã³ã¹ãã©ã¯ã¿ã¼
X( std::initializer_list<int> ) { }
X( std::initializer_list<double> ) { }
// ãã®ä»ã®ã³ã³ã¹ãã©ã¯ã¿ã¼
X( int, int, int ) { }
X( double, double, double ) { }
} ;
int main()
{
X a = { 1, 2, 3 } ; // ãªã¼ãã¼ãã¼ã解決ãX::X( std::initializer_list<int> )
X b = { 1.0, 2.0, 3.0 } ; // ãªã¼ãã¼ãã¼ã解決ãX::X( std::initializer_list<double> )
}
ãã®å ´åãåè£é¢æ°ã«ã¯ãåæåãªã¹ãã³ã³ã¹ãã©ã¯ã¿ã¼ããåæãããªãã
ãããä¸æ®µéç®ã®åå解決ã§ãé©åãªåæåãªã¹ãã³ã³ã¹ãã©ã¯ã¿ã¼ãè¦ã¤ãããªãã£ãå ´åãäºæ®µéã®åè£é¢æ°ã¨ãã¦ãåã³ãªã¼ãã¼ãã¼ã解決ãè¡ããããä»åº¦ã¯ãã¯ã©ã¹ã®ãã¹ã¦ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ãåè£é¢æ°ã¨ãã¦åæããããå®å¼æ°ã¯ãåæåãªã¹ãã®ä¸ã®è¦ç´ ããããããå¥ã®å®å¼æ°ã¨ãã¦æ¸¡ãããã
struct X
{
// é©åãªåæåãªã¹ãã³ã³ã¹ãã©ã¯ã¿ã¼ãªã
X( int, int, int ) { }
X( double, double, double ) { }
X( int, double, int ) { }
} ;
int main()
{
X a = { 1, 2, 3 } ; // ãªã¼ãã¼ãã¼ã解決ãX::X( int, int, int )
X b = { 1.0, 2.0, 3.0 } ; // ãªã¼ãã¼ãã¼ã解決ãX::X( double, double, double )
X c = { 1, 2.0, 3 } ; // ãªã¼ãã¼ãã¼ã解決ãX::X( int, double, int )
}
ãé©åãã¨ããç¨èªã«æ³¨æãããã¨ãããã縮å°å¤æãå¿
è¦ã¨ãªãã°ãé©åé¢æ°ãã©ãããå¤å®ããåã«ã¨ã©ã¼ã¨ãªãã
struct X
{
X( std::initializer_list<int> ) { }
X( double, double, double ) { }
} ;
int main()
{
X b = { 1.0, 2.0, 3.0 } ; // ã¨ã©ã¼ã縮å°å¤æãå¿
è¦
}
ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãæã¤ã¯ã©ã¹ã«ç©ºã®åæåãªã¹ãã渡ãããå ´åãä¸æ®µéç®ã®ãªã¼ãã¼ãã¼ã解決ã¯è¡ããããããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãå¼ã°ããã
struct X
{
X( ) { }
template < typename T >
X( std::initializer_list<T> ) { }
} ;
int main()
{
X x = { } ; // ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ã¼ãå¼ã°ãã
}
ã³ãã¼ãªã¹ãåæåã§ã¯ãexplicitã³ã³ã¹ãã©ã¯ã¿ã¼ãé¸ã°ããå ´åãã¨ã©ã¼ã¨ãªãã
struct X
{
explicit X( int ) { }
} ;
int main()
{
X a = { 0 } ; // ã¨ã©ã¼ãã³ãã¼ãªã¹ãåæåã§explicitã³ã³ã¹ãã©ã¯ã¿ã¼
X b{ 0 } ; // OKãç´æ¥åæå
}
åè£é¢æ°ã¯ãåã«ååæ¢ç´¢ã®çµæã§ãããå®éã«ã¯å¼ã³åºããã¨ãã§ããªãé¢æ°ãå«ã¾ãã¦ããããã®ãããåè£é¢æ°ãåæããå¾ãå¼ã³åºããã¨ãåºæ¥ãé¢æ°ãããªãã¡é©åé¢æ°(Viable functions)ãåæããã
é©åé¢æ°ã¨ã¯ãä¸ããããå®å¼æ°ã§ãå®éã«å¼ã³åºããã¨ãåºæ¥ãé¢æ°ã§ãããããã«ã¯ã大ããäºã¤ã®è¦ç´ ããããä»®å¼æ°ã®æ°ã¨åã§ããã
é©åé¢æ°ã¨ãªãããã«ã¯ã¾ããä¸ããããå®å¼æ°ã®åæ°ã«å¯¾ãã¦ãä»®å¼æ°ã®åæ°ã対å¿ãã¦ããªããã°ãªããªãããã®ããã®æ¡ä»¶ã¯ã以ä¸ã®ãããããæºããã¦ããã°ããã
-
å®å¼æ°ã®åæ°ã¨ãåè£é¢æ°ã®ä»®å¼æ°ã®åæ°ãä¸è´ããé¢æ°
ããã¯ç°¡åã ãå®å¼æ°ã¨åãåæ°ã ãã®ä»®å¼æ°ãããã°ãããå¯å¤é·ãã³ãã¬ã¼ãã®ã¤ã³ã¹ã¿ã³ã¹åã«ããé¢æ°ããã®ãã¡ã«å
¥ãã
void f( int, int ) { }
int main()
{
f( 0, 0 ) ; // OK
f( 0 ) ; // ã¨ã©ã¼
}
-
åè£é¢æ°ã®ä»®å¼æ°ã®åæ°ããå®å¼æ°ã®åæ°ããå°ãªãããä»®å¼æ°ãªã¹ãã«ã¨ãªãã·ã¹(...)ãããå ´åã
ããã¯ãCè¨èªã§ã馴æã¿ã®...ã®ãã¨ã ãå¯å¤é·ãã³ãã¬ã¼ãã¯ããã®ãã¡ã«ã¯å
¥ããªãã
void f( int, ... ) ;
int main()
{
f( 0 ) ; // é©åé¢æ°
f( 0, 1 ) ; // é©åé¢æ°
f( 0, 1, 2, 3, 4, 5 ) ; // é©åé¢æ°
}
-
åè£é¢æ°ã®ä»®å¼æ°ã®åæ°ã¯ãå®å¼æ°ããå¤ãããå®å¼æ°ããå¤ãä»®å¼æ°ã«ã¯ãã¹ã¦ãããã©ã«ãå®å¼æ°ãæå®ããã¦ãããã¨ã
void f( int, int = 0, int = 0, int = 0, int = 0, int = 0 ) ;
int main()
{
f( 0 ) ; // é©åé¢æ°
f( 0, 1 ) ; // é©åé¢æ°
f( 0, 1, 2, 3, 4, 5 ) ; // é©åé¢æ°
}
ããã«ã対å¿ããå®å¼æ°ããä»®å¼æ°ã«å¯¾ãã¦ãå¾è¿°ããæé»ã®åå¤æã«ããã妥å½ãªå¤æãåå¨ããªããã°ãªããªãã
void f( int ) { }
int main()
{
f( 0 ) ; // OKãå®å
¨ä¸è´
f( 0L ) ; // OKãæ´æ°å¤æ
f( 0.0 ) ; // OKãæ´æ°ã¨æµ®åå°æ°ç¹æ°éã®å¤æ
f( &f ) ; // ã¨ã©ã¼
}
é©åé¢æ°ã§ããããã¨ãã£ã¦ãå®éã«å¼ã³åºããã¨ã¯éããªãããã¨ãã°ã宣è¨ããã¦ãããæªå®ç¾©ã§ãã£ãããã¢ã¯ã»ã¹æå®ã«ããå¶éãåãããããããã¯ãã®ä»å®è£
ä¾åã®çç±ãªã©ãç¾å®ã«ã¯å¼ã³åºããã¨ãã§ããªãçç±ã¯å¤æ°åå¨ããã
é©åé¢æ°ãè¤æ°ããå ´åãå®ããããæ¹æ³ã§é¢æ°ãæ¯è¼ãããã¨ã«ãã£ã¦ãã²ã¨ã¤ã®æãé©å(best viable)ãªé¢æ°ãé¸æããããã®é¢æ°ãæé©é¢æ°ã¨å¼ã¶ããªã¼ãã¼ãã¼ã解決ã®çµæã¯ããã®æé©é¢æ°ã¨ãªãããããæãé©åãªé¢æ°ãã²ã¨ã¤ã«æ±ºå®ã§ããªãå ´åããªã¼ãã¼ãã¼ã解決ã¯ææ§ã§ãããã¨ã©ã¼ã¨ãªãã
æé©é¢æ°ã®æ±ºå®ã¯ã主ã«ãå¾è¿°ããæé»ã®åå¤æã®åªå
é ä½ã«ãã£ã¦æ±ºå®ãããã
ã¾ã大åæã¨ãã¦ãããé¢æ°ããå¥ã®é¢æ°ããããããé©åã§ããã¨å¤æãããã«ã¯ãããé¢æ°ã®ãã¹ã¦ä»®å¼æ°ã«å¯¾ããå®å¼æ°ããã®æé»ã®åå¤æã®åªå
é ä½ãå£ã£ã¦ãããããã¤ãã²ã¨ã¤ä»¥ä¸ã®åªãã¦ããåå¤æãåå¨ããªããã°ãªããªãã
void f( int, double ) { } // #1
void f( long, int ) { } // #2
int main()
{
f( 0 , 0 ) ; // ã¨ã©ã¼ããªã¼ãã¼ãã¼ã解決ãææ§
}
ãã®ä¾ã§ã¯ãã©ã®é¢æ°ããä»®å¼æ°ã¸ã®åå¤æã®åªå
é ä½ããä»ã®é¢æ°ããå£ã£ã¦ããããããã£ã¦ãªã¼ãã¼ãã¼ã解決ã¯ææ§ã¨ãªããä¸è¦ããã¨ã#2ã®æ¹ããã©ã¡ããæ´æ°åã§ããã®ã§ãããããåè£ãªã®ã§ã¯ãªããã¨æããããããªãããããã#1ã®ç¬¬ä¸ä»®å¼æ°ã®åã¯intãªã®ã§ãlongãããåªãã¦ãããä¸æ¹ã第äºå¼æ°ã§ã¯ã#2ã®æ¹ãåªãã¦ããããã®ãããææ§ã¨ãªããæé©é¢æ°ã¨ãªãããã«ã¯ãå
¨ã¦ã®ä»®å¼æ°ã®åããä»ã®åè£ããå£ã£ã¦ãã¦ã¯ãªããªãã®ã ã
ã¦ã¼ã¶ã¼å®ç¾©åå¤æã«ããåæåã®å ´åãã¦ã¼ã¶ã¼å®ç¾©åå¤æã®çµæã®åãããç®çã®åã¸ãæ¨æºåå¤æã«ããå¤æããéãããåªå
é ä½ã®é«ããã®ãé¸ã°ããã
struct X
{
operator int() ;
operator double() ;
} ;
void f()
{
X x ;
int i = x ; // operator intãæé©é¢æ°
float f = x ; // ã¨ã©ã¼ãææ§
}
ä¸è¦ããã¨ãdoubleããfloatã¸ã®å¤æã¯ãintããã®å¤æããåªå
é ä½ãé«ãã®ã§ã¯ãªããã¨æããããããªãããå¾è¿°ããæ¨æºåå¤æã®åªå
é ä½ã®ã«ã¼ã«ã«ãããåãåªå
é ä½ãªã®ã§ãææ§ã¨ãªãã
éãã³ãã¬ã¼ãé¢æ°ã¨é¢æ°ãã³ãã¬ã¼ãã®ç¹æ®åã§ã¯ãéãã³ãã¬ã¼ãé¢æ°ãåªå
ãããã
template < typename T >
void f( T ) ;
void f( int ) ;
int main()
{
f( 0 ) ; // éãã³ãã¬ã¼ãé¢æ°ãåªå
}
ãã¡ãããããã¯å¤§åæã®ããã¹ã¦ã®ä»®å¼æ°ã«å¯¾ãå£ã£ãåå¤æããªãã¨ãããã¨ãæãç«ã¤ä¸ã§ã®è©±ã§ããã
template < typename T >
void f( T ) ;
void f( long ) ;
int main()
{
f( 0 ) ; // é¢æ°ãã³ãã¬ã¼ãã®ç¹æ®åf<int>ãåªå
}
ãã®å ´åã¯ããã³ãã¬ã¼ãã®ç¹æ®åã§ããä»®å¼æ°intåã®æ¹ããå®å¼æ°intåã«å¯¾ãã¦ãããåªããåå¤æãªã®ã§ãåªå
ãããã
ãã³ãã¬ã¼ãã®å®å¼æ°æ¨å®ã®ã«ã¼ã«ã¯è¤éãªã®ã§ãä¸è¦ãã¦ãéãã³ãã¬ã¼ãé¢æ°ãåªå
ãããã¨æãããã³ã¼ãã§ãé¢æ°ãã³ãã¬ã¼ãã®å®ä½åã®æ¹ãåªå
ãããå ´åãããã
// #1
// éãã³ãã¬ã¼ãé¢æ°
void f( int const & ) ;
// #2
// é¢æ°ãã³ãã¬ã¼ã
template < typename T >
void f( T && ) ;
int main()
{
int x = 0 ; // xã¯éconstãªlvalue
f( x ) ; // #2ãå¼ã¶
}
ããã¯ã#2ã®å®ä½åã®çµæããf<int &>( int & )ã«ãªãããã ãxã¯éconstãªlvalueã§ããã®ã§ãéconstãªlvalueãªãã¡ã¬ã³ã¹åã®ä»®å¼æ°ã¨åã#2ã®æ¹ãåªå
ãããã
ãµãã¤ã®é¢æ°ã両æ¹ã¨ããã³ãã¬ã¼ãã®ç¹æ®åã®å ´åãåé åºã«ãã£ã¦ãããç¹æ®åããã¦ããã¨å¤æãããæ¹ããåªå
ãããã
template < typename T > void f( T ) ; // #1
template < typename T > void f( T * ) ; // #2
int main()
{
int * ptr = nullptr ;
f( ptr ) ; // åé åºã«ãã#2ãåªå
}
#1ã¨#2ã®ç¹æ®åã«ããä»®å¼æ°ã®åã¯ãã©ã¡ãã int *ã§ãããã#2ã®ãã³ãã¬ã¼ãã®ç¹æ®åã®æ¹ããåé åºã®ã«ã¼ã«ã«ãã£ã¦ãããç¹æ®åããã¦ããã¨ã¿ãªãããããã#2ãåªå
ãããã
æé»ã®åå¤æã«ã¯ãããã¤ãã®ç¨®é¡ã¨ãå¤æ°ã®ä¾å¤ã«ã¼ã«ããããããããåªå
é ä½ãæ¯è¼ãããã¨ãã§ãããæ®å¿µãªããããã®è©³ç´°ã¯é常ã«åé·ã§ãããæ¬æ¸ã§ã¯æ¦ç¥ã®èª¬æã«çããã
ã¾ããæé»ã®åå¤æã«ã¯ã大å¥ãã¦ä¸ç¨®é¡ãããæ¨æºåå¤æãã¦ã¼ã¶ã¼å®ç¾©åå¤æãã¨ãªãã·ã¹å¤æã§ãããåªå
é ä½ããã®ä¸¦ã³ã§ãããæ¨æºåå¤æãä¸çªåªå
ããã次ã«ã¦ã¼ã¶ã¼å®ç¾©åå¤æãæå¾ã«ã¨ãªãã·ã¹å¤æã¨ãªãã
struct X { X(int) ; } ;
void f( long ) ; // #1
void f( X ) ; // #2
void g( X ) ; // #3
void g( ... ) ; // #4
int main()
{
f( 0 ) ; // #1ãæ¨æºåå¤æãã¦ã¼ã¶ã¼å®ç¾©åå¤æã«åªå
ããã
g( 0 ) ; // #3ãã¦ã¼ã¶ã¼å®ç¾©åå¤æãã¨ãªãã·ã¹å¤æã«åªå
ããã
}
ããã«ãæ¨æºåå¤æã¨ã¦ã¼ã¶ã¼å®ç¾©å¤æå士ã®éã§ã®åªå
é ä½ãããã
ã¨ãªãã·ã¹ã«åºæ¬å以å¤ã渡ãã¦å¼ã³åºããå ´åã®æåã¯æªå®ç¾©ã ãããªã¼ãã¼ãã¼ã解決ã«ã¯å½±é¿ããªãã
ãªã¼ãã¼ãã¼ã解決ã«ãããæ¨æºåå¤æã®éã®åªå
é ä½ã¯ãé常ã«è¤éã§ãåã«ãã©ã³ã¯Aï¼ã©ã³ã¯Bã®ãããªåç´ãªæ¯è¼ãã§ããªããããã§ã¯ãã¨ãã«åé¡ã«ãªããããªé¨åã®ã¿åãä¸ããã
ã¾ããåå¤æã®å¿
è¦ã®ãªããå®å
¨ä¸è´ãæãåªå
ãããã
void f( int ) ;
void f( double ) ;
int main()
{
f( 0 ) ; // f(int)
f( 0.0 ) ; // f(double)
}
ãã®å®å
¨ä¸è´ã«ã¯ãlvalueããrvalueã¸ã®åå¤æãé
åãããã¤ã³ã¿ã¼ã¸ã®åå¤æãé¢æ°ãããã¤ã³ã¿ã¼ã¸ã®åå¤æãå«ã¾ããã
void f( int ) ;
int main()
{
int x = 0 ;
f( x ) ; // lvalueããrvalueã¸ã®å¤æ
}
é
åãé¢æ°ãããã¤ã³ã¿ã¼ã¸ã®å¤æã¯ãå®å
¨ä¸è´ã¨ã¿ãªããããã¨ã«æ³¨æã
void g( ) ;
void f( void (*)() ) ; // ãã¤ã³ã¿ã¼
void f( void (&)() ) ; // ãªãã¡ã¬ã³ã¹
int main()
{
f( g ) ; // ã¨ã©ã¼ããªã¼ãã¼ãã¼ã解決ãææ§ãåè£é¢æ°ã¯ãã¹ã¦å®å
¨ä¸è´
f( &g ) ; // OKãf( void (*)() )
}
å®å
¨ä¸è´ã¯ããã¤ã³ã¿ã¼ããªãã¡ã¬ã³ã¹ã«CV修飾åãä»ãå ããåå¤æããåªå
ãããã
void f( int & ) ; // #1
void f( int const & ) ; // #2
int main()
{
int x = 0 ;
f( x ) ; // #1ãå®å
¨ä¸è´
}
æ´æ°ã¨æµ®åå°æ°ç¹æ°ã®ããã¢ã¼ã·ã§ã³ã¯ããã®ä»ã®æ´æ°ã¨æµ®åå°æ°ç¹æ°ã¸ã®å¤æããåªå
ãããã
void f( int ) ;
void f( long ) ;
int main()
{
short x = 0 ;
f( x ) ; // f(int)ãããã¢ã¼ã·ã§ã³
}
ããé¢æ°ã®ååã«å¯¾ãã¦ãè¤æ°ã®åè£é¢æ°ãããå ´åã§ããååããé¢æ°ã®ã¢ãã¬ã¹ãåå¾ã§ãããã©ã®åè£é¢æ°ãé¸ã¶ãã¯ãæèãæå¾
ããåã®å®å
¨ä¸è´ã§æ±ºå®ããããåæåã代å
¥ãé¢æ°å¼ã³åºãã®å®å¼æ°ãæ示çãªãã£ã¹ãã®ä»ã«ãé¢æ°ã®æ»ãå¤ããæèã«ãã決å®ãããã
void f( int ) ;
void f( long ) ;
void g( void (*)(int) ) ;
void h()
{
// åæå
void (*p)(int) = &f ; // void f(int)ã®ã¢ãã¬ã¹
// 代å
¥
p = &f ; // void f(int)ã®ã¢ãã¬ã¹
// é¢æ°å¼ã³åºãã®å®å¼æ°
g( &f ) ;
// æ示çãªãã£ã¹ã
static_cast<void (*)(int)>(&f) ; // void f(int)ã®ã¢ãã¬ã¹
}
// é¢æ°ã®æ»ãå¤
auto i() -> void (*)(int)
{
return &f ; // void f(int)ã®ã¢ãã¬ã¹
}
ãããã®æèã§ã¯ãããå
·ä½çãªå®å
¨ä¸è´ã®åãæå¾
ãã¦ããã®ã§ããªã¼ãã¼ãã¼ããããé¢æ°åãããé©åãªé¢æ°ã決å®ã§ããã
å®å
¨ä¸è´ã®åã§ã¯ãªãå ´åããåã決å®ã§ããªãå ´åã¯ã¨ã©ã¼ã§ããã
void f( int ) ;
void f( long ) ;
template < typename T >
void g( T ) { }
int main()
{
g( &f ) ; // ã¨ã©ã¼
}
ç¹å¥ãªèå¥åã使ã£ã¦ããé¢æ°å®£è¨ã¯ãæ¼ç®åé¢æ°(operator function)ã¨ãã¦èªèãããããã®èå¥åã¯ä»¥ä¸ã®ããã«ãªãã
operator æ¼ç®å
ãªã¼ãã¼ãã¼ãå¯è½ãªæ¼ç®åã¯ä»¥ä¸ã®éãã§ããã
new delete new[] delete[]
+ - * / % Ë & | ~
! = < > += -= *= /= %=
Ë= &= |= << >> >>= <<= == !=
<= >= && || ++ -- , ->* ->
( ) [ ]
以ä¸ã®æ¼ç®åã¯ãåé
ãäºé
ã®ä¸¡æ¹ã§ãªã¼ãã¼ãã¼ãã§ããã
+ - * &
以ä¸ã®æ¼ç®åã¯ãé¢æ°å¼ã³åºãã¨æ·»ãåã§ããã
( ) [ ]
以ä¸ã®æ¼ç®åã¯ããªã¼ãã¼ãã¼ãã§ããªãã
. .* :: ?:
new, new[], delete, delete[]ã«ã¤ãã¦ã¯ã確ä¿é¢æ°ã¨è§£æ¾é¢æ°ãåç
§ã
æ¼ç®åé¢æ°ã¯ãéstaticã¡ã³ãã¼é¢æ°ããéã¡ã³ãã¼é¢æ°ã§ãªããã°ãªããªããéstaticã¡ã³ãã¼é¢æ°ã®å ´åãæé»ã®ãªãã¸ã§ã¯ãä»®å¼æ°ãã第ä¸ãªãã©ã³ãã«ãªããããã*thisã§ããã
éã¡ã³ãã¼é¢æ°ã®å ´åãä»®å¼æ°ã®ã²ã¨ã¤ã¯ãã¯ã©ã¹ããã¯ã©ã¹ã¸ã®ãªãã¡ã¬ã³ã¹ãenumãenumã¸ã®ãªãã¡ã¬ã³ã¹ã§ãªããã°ãªããªãã
struct X
{
// éstaticã¡ã³ãã¼é¢æ°ã«ããæ¼ç®åé¢æ°
X operator +() const ; // æé»ã®ãªãã¸ã§ã¯ãä»®å¼æ° X const &
X operator +( int ) const ; // æé»ã®ãªãã¸ã§ã¯ãä»®å¼æ° X const &
} ;
// éã¡ã³ãã¼é¢æ°ã«ããæ¼ç®åé¢æ°
X operator -( X const & ) ;
X operator -( X const &, int ) ;
X operator -( int, X const & ) ;
以ä¸ã®ä¾ã¯ã¨ã©ã¼ã§ããã
// ã¨ã©ã¼ãçµã¿è¾¼ã¿ã®æ¼ç®åããªã¼ãã¼ãã¼ãã§ããªã
int operator +( int, int ) ;
struct X { } ;
// ã¨ã©ã¼ãçµã¿è¾¼ã¿ã®æ¼ç®åããªã¼ãã¼ãã¼ãã§ããªã
X operator + ( X * ) ;
ãã ãã代å
¥æ¼ç®åãæ·»åæ¼ç®åã®ããã«ãéstaticã¡ã³ãã¼é¢æ°ã¨ãã¦å®è£
ããªããã°ãªããªãä¾å¤çãªæ¼ç®åãããã
æ¼ç®åé¢æ°ã¯ãå¿
ãå
ã®æ¼ç®åã¨åãæ°ã®ä»®å¼æ°ãåããªããã°ãªããªãã
struct X { } ;
X operator / ( X & ) ; // ã¨ã©ã¼ãä»®å¼æ°ãå°ãªã
X operator / ( X &, X &, X & ) ; // ã¨ã©ã¼ãä»®å¼æ°ãå¤ã
ãã ãããããé¢æ°å¼ã³åºãæ¼ç®åã®ããã«ãä¾å¤çãªæ¼ç®åãããã
æ¼ç®åé¢æ°ã¯ãçµã¿è¾¼ã¿ã®æ¼ç®åã¨åãæåãå®ããªãã¦ããããä¾ãã°ãæ»ãå¤ã®åã¯èªç±ã§ãããããªã¼ãã¼ãã¼ããããæ¼ç®åé¢æ°ããåºæ¬åã«ãã®åé
æ¼ç®åãé©ç¨ããå ´åã«æå¾
ãããæåãããªãã¦ããã¾ããªããä¾ãã°ããªã¼ãã¼ãã¼ãããæ¼ç®åé¢æ°ã§ã¯ã"++a"ãã¨ã"a += 1"ã¨ãããµãã¤ã®å¼ãè©ä¾¡ããéã®æåãçµæãåãã«ãªããªãã¦ããããã¾ããçµã¿è¾¼ã¿æ¼ç®åãªãã°éconstãªlvalueã渡ãæ¼ç®åã§ãconstãªlvalueãrvalueãåãåã£ã¦ãæ§ããªãã
struct X { } ;
void operator + ( X & ) ; // OKãæ»ãå¤ã®åã¯èªç±
void operator ++ ( X const & ) ; // OKãconstãªlvalueãªãã¡ã¬ã³ã¹ã§ããã
æ¼ç®åé¢æ°ã¯ãé常éãæ¼ç®åã使ããã¨ã«ãã£ã¦å¼ã³åºããã¨ãã§ããããã®éãæ¼ç®åã®åªå
é ä½ã¯ãçµã¿è¾¼ã¿ã®æ¼ç®åã¨å¤ãããªããã¾ããèå¥åãæå®ãããã¨ã«ãã£ã¦ãé常ã®é¢æ°å¼ã³åºãå¼ã®ææ³ã§ãæ示çã«å¼ã³åºããã¨ãã§ããã
struct X
{
X operator +( X const & ) const ;
X operator *( X const & ) const ;
} ;
int main()
{
X a ; X b ; X c ;
a + b ; // æ¼ç®åã使ããã¨ã«ããå¼ã³åºã
a + b * c ; // åªå
é ä½ã¯ã(a + (b * c))
a.operator +(b) ; // æ示çãªé¢æ°å¼ã³åºã
}
代å
¥æ¼ç®å=ããåé
æ¼ç®åã®&ããã«ã³ãæ¼ç®åã¯ããªã¼ãã¼ãã¼ãããªãã¦ããã¹ã¦ã®åã«å¯¾ãã¦ãããããå®ç¾©ãããæåãããããã®æåã¯ãªã¼ãã¼ãã¼ããã¦å¤ãããã¨ãã§ããã
ãªã¼ãã¼ãã¼ãå¯è½ãªåé
æ¼ç®åã¯ã以ä¸ã®éãã§ããã
+ - * & ~ !
ããã§ã¯ã*ã¨&ã¯åé
æ¼ç®åã§ãããã¨ã«æ³¨æãäºé
æ¼ç®åã®é
ãåç
§ã
ã¤ã³ã¯ãªã¡ã³ãæ¼ç®åã¨ãã¯ãªã¡ã³ãæ¼ç®åã«ã¤ãã¦ã¯ãã¤ã³ã¯ãªã¡ã³ãã¨ãã¯ãªã¡ã³ããåç
§ã
åé
æ¼ç®åã¯ãæ¼ç®åã@ã¨ããã¨ã@xã¨ããå¼ã¯ãéstaticã¡ã³ãã¼é¢æ°ã®å ´åãx.operator @()ãéã¡ã³ãã¼é¢æ°ã®å ´åãoperator @(x)ã¨ãã¦å¼ã³åºããããåé
æ¼ç®åã§ã¯ãéstaticã¡ã³ãã¼é¢æ°ã¨éã¡ã³ãã¼é¢æ°ã¯ãæ©è½çã«éãã¯ãªãã
struct X
{
void operator + () ;
} ;
void operator -( X & ) ;
int main()
{
X x ;
+x ; // x.operator + ()
-x ; // operator - (x)
}
éstaticã¡ã³ãã¼é¢æ°ã®å ´åãæ示çã«ä»®å¼æ°ãã¨ããªããæé»ã®ãªãã¸ã§ã¯ããä»®å¼æ°ã¨ãã¦æ¸¡ãããã
struct X
{
void operator + () & ;
void operator + () const & ;
void operator + () volatile & ;
void operator + () const volatile & ;
void operator + () && ;
void operator + () const && ;
void operator + () volatile && ;
void operator + () const volatile && ;
} ;
int main()
{
X x ;
+x ; // void operator + () &
+static_cast<X &&>(x) ; // void operator + () &&
X const cx ;
+x ; // void operator + () const &
}
åæ§ã®ã³ã¼ãããéã¡ã³ãã¼é¢æ°ã¨ãã¦æ¸ãã¨ã以ä¸ã®ããã«ãªãã
struct X { } ;
void operator + ( X & ) ;
void operator + ( X const & ) ;
void operator + ( X volatile & ) ;
void operator + ( X const volatile & ) ;
void operator + ( X && ) ;
void operator + ( X const && ) ;
void operator + ( X volatile && ) ;
void operator + ( X const volatile && ) ;
int main()
{
X x ;
+x ; // void operator + ( X & )
+static_cast<X &&>(x) ; // void operator + ( X && )
X const cx ;
+x ; // void operator + ( X const & )
}
ã¾ããéã¡ã³ãã¼é¢æ°ã®å ´åã¯ãã¯ã©ã¹åãå¼æ°ã«åããã¨ãã§ããã
struct X { } ;
void operator + ( X ) ;
operator &ã«ã¯ã注æãè¦ãããããã¯ãçµã¿è¾¼ã¿ã®æ¼ç®åãããªãã¡ããªãã©ã³ãã®ã¢ãã¬ã¹ãå¾ãæ¼ç®åã¨ãã¦ããã¹ã¦ã®åã«ãããããå®ç¾©ããã¦ããã
// operator &ã®ãªã¼ãã¼ãã¼ããªã
struct X { } ;
int main()
{
X x ;
X * ptr = &x ; // çµã¿è¾¼ã¿ã®operator &ã®å¼ã³åºã
}
ãã®æ¼ç®åããªã¼ãã¼ãã¼ãããã¨ãçµã¿è¾¼ã¿ã®operator &ãåããªããªãã
struct X
{
X * operator &() { return nullptr ; }
} ;
int main()
{
X x ;
X * ptr = &x ; // 常ã«nullãã¤ã³ã¿ã¼ã«ãªãã
}
ãã¡ãããæ»ãå¤ã®åã¯èªç±ã ããããªã«ãå¥ã®ãã¨ããããã®ãå¯è½ã ã
class int_wrapper
{
private :
int obj ;
public :
int * operator &() { return &obj ; }
} ;
int main()
{
int_wrapper wrap ;
int * ptr = &wrap ;
}
ãã ããã¯ã©ã¹ã®ã¦ã¼ã¶ã¼ãããªãã¸ã§ã¯ãã®ã¢ãã¬ã¹ãå¾ããå ´åãçµã¿è¾¼ã¿ã®æ¼ç®åãå¼ã³åºãã®ã¯ç°¡åã§ã¯ãªãããã®ãããæ¨æºã©ã¤ãã©ãªãããã¼<memory>ã«ã¯ãstd::addressofã¨ããé¢æ°ãã³ãã¬ã¼ããå®ç¾©ããã¦ãããããã使ãã°ãoperator &ããªã¼ãã¼ãã¼ãããã¦ããã¯ã©ã¹ã§ããã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã®ã¢ãã¬ã¹ãå¾ããã¨ãã§ããã
struct X
{
void operator &() { }
} ;
int main()
{
X x ;
X * p1 = &x ; // ã¨ã©ã¼ãoperator &ã®æ»ãå¤ã®åã¯void
X * ptr = std::addressof(x) ; // OK
}
ãªã¼ãã¼ãã¼ãå¯è½ãªäºé
æ¼ç®åã¯ä»¥ä¸ã®éãã§ããã
+ - * / % ^ & | ~
! < > += -= *= /= %=
^= &= |= << >> >>= <<= == !=
<= >= && || ,
代å
¥æ¼ç®åã¯ç¹å¥ãªæ±ããåããã詳ããã¯ã代å
¥æ¼ç®åãåç
§ãè¤å代å
¥æ¼ç®åã¯ãäºé
æ¼ç®åã«å«ã¾ããã
äºé
æ¼ç®åã¯ãæ¼ç®åã@ã¨ããã¨ãx@yã¨ããå¼ã«å¯¾ãã¦ãéstaticã¡ã³ãã¼é¢æ°ã®å ´åãx.operator @(y)ãéã¡ã³ãã¼é¢æ°ã®å ´åãoperator @(x,y)ã®ããã«å¼ã³åºãããã
struct X
{
void operator + (int) const ;
} ;
void operator - ( X const &, int ) ;
int main()
{
X x ;
x + 1 ; // x.operator +(1)
x - 1 ; // operator -(x, 1)
}
éstaticã¡ã³ãã¼é¢æ°ã®å ´åã第ä¸ãªãã©ã³ããæé»ã®ãªãã¸ã§ã¯ãä»®å¼æ°ã«ã第äºãªãã©ã³ããå®å¼æ°ã«æ¸¡ãããã
struct X
{
void operator + (int) & ;
void operator + (int) const & ;
void operator + (int) volatile & ;
void operator + (int) const volatile & ;
void operator + (int) && ;
void operator + (int) const && ;
void operator + (int) volatile && ;
void operator + (int) const volatile && ;
} ;
int main()
{
X x ;
x + 1 ; // X::operator + (int) &
static_cast<X &&>(x) + 1 ; // X::operator + (int) &&
X const cx ;
cx + 1 ; // X::operator + (int) const &
}
åæ§ã®ã³ã¼ãããéã¡ã³ãã¼é¢æ°ã§æ¸ãã¨ä»¥ä¸ã®ããã«ãªãã
struct X { } ;
void operator + ( X &, int) ;
void operator + ( X const &, int) ;
void operator + ( X volatile &, int) ;
void operator + ( X const volatile &, int) ;
void operator + ( X &&, int) ;
void operator + ( X const &&, int) ;
void operator + ( X volatile &&, int) ;
void operator + ( X const volatile &&, int) ;
int main()
{
X x ;
x + 1 ; // operator + ( X &, int)
static_cast<X &&>(x) + 1 ; // operator + ( X &&, int)
X const cx ;
cx + 1 ; // operator + ( X const &, int)
}
éã¡ã³ãã¼é¢æ°ã®å ´åã¯ãã¯ã©ã¹åãä»®å¼æ°ã«åããã¨ãã§ããã
struct X { } ;
void operator + ( X, int ) ;
第äºãªãã©ã³ãã«ã¯ã©ã¹ãenumåããããã¯ãã®ãªãã¡ã¬ã³ã¹åãåãããå ´åã¯ãéã¡ã³ãã¼é¢æ°ãã使ããªãã
struct X { } ;
void operator + ( int, X & ) ;
int main()
{
X x ;
1 + x ;
}
ã¡ã³ãã¼é¢æ°ã«ãããªã¼ãã¼ãã¼ãã§ã¯ãå¿
ã第ä¸ãªãã©ã³ãã®ã¡ã³ãã¼ã¨ãã¦æ¼ç®åé¢æ°ããã°ããã®ã§ãããã¯ã§ããªãã
ã«ã³ãæ¼ç®åãoperator ,ã«ã¯ããããããå®ç¾©ãããçµã¿è¾¼ã¿ã®æ¼ç®åãåå¨ããããªã¼ããã¼ãã«ããããã®æåãå¤ãããã¨ãã§ããããã ããoperator ,ã®æåãå¤ããã®ã¯ãã¦ã¼ã¶ã¼ãæ··ä¹±ãããã®ã§ãæ
ãã¹ãã§ããããããåã«ä»»æåã®å¼æ°ãåãããã¨ããã®ã§ããã°ãå¯å¤é·ãã³ãã¬ã¼ããåæåãªã¹ããªã©ã®ä¾¿å©ãªæ©è½ãä»ã«ãããã
代å
¥æ¼ç®åã®ãªã¼ãã¼ãã¼ãã¯ãä»®å¼æ°ãã²ã¨ã¤ã¨ãéstaticã¡ã³ãã¼é¢æ°ã¨ãã¦å®è£
ãããéã¡ã³ãã¼é¢æ°ã¨ãã¦å®è£
ãããã¨ã¯ã§ããªããè¤å代å
¥æ¼ç®åã¯ã代å
¥æ¼ç®åã§ã¯ãªããäºé
æ¼ç®åã§ããã
struct X
{
// ã³ãã¼ä»£å
¥æ¼ç®å
X & operator = ( X const & ) ;
// ã ã¼ã代å
¥æ¼ç®å
X & operator = ( X && ) ;
// intããã®ä»£å
¥æ¼ç®å
X & operator = ( int ) ;
} ;
// ã¨ã©ã¼ãéã¡ã³ãã¼é¢æ°ã¨ãã¦å®£è¨ãããã¨ã¯ã§ããªã
X & operator = ( X &, double ) ;
// OKãè¤å代å
¥æ¼ç®åã¯äºé
æ¼ç®å
X & operator += ( X &, double ) ;
ãã¡ãããæ»ãå¤ã®åã¯èªç±ã§ããããã ããæ
£ä¾ã¨ãã¦ãæé»ã«å®ç¾©ããã代å
¥æ¼ç®åã¯ã*thisãè¿ãããã«ãªã£ã¦ããã詳ããã¯ãã¯ã©ã¹ãªãã¸ã§ã¯ãã®ã³ãã¼ã¨ã ã¼ããåç
§ã
é¢æ°å¼ã³åºãæ¼ç®åã®èå¥åã¯ãoperator ()ã§ãããé¢æ°å¼ã³åºãæ¼ç®åã®ãªã¼ãã¼ãã¼ãã¯ãä»»æåã®ä»®å¼æ°ãæã¤éstaticã¡ã³ãã¼é¢æ°ã¨ãã¦å®£è¨ãããéã¡ã³ãã¼é¢æ°ã¨ãã¦å®£è¨ãããã¨ã¯ã§ããªããããã©ã«ãå®å¼æ°ã使ããã¨ãã§ããã
é¢æ°å¼ã³åºãæ¼ç®åã¯ãx(arg1, ...)ã¨ããã¨ãx.operator()(arg1, ...)ã®ããã«å¼ã³åºãããã
struct X
{
void operator () ( ) ;
void operator () ( int ) ;
void operator () ( int, int, int = 0 ) ;
} ;
int main()
{
X x ;
x() ; // x.operator () ( )
x( 0 ) ; // x.operator () ( 0 )
x( 1, 2 ) ; // x.operator() ( 1, 2 )
}
æ·»åæ¼ç®åã®èå¥åã¯ãoperator []ã§ãããæ·»åæ¼ç®åã®ãªã¼ãã¼ãã¼ãã¯ãã²ã¨ã¤ã®ä»®å¼æ°ãæã¤éstaticã¡ã³ãã¼é¢æ°ã¨ãã¦å®£è¨ãããéã¡ã³ãã¼é¢æ°ã¨ãã¦å®£è¨ãããã¨ã¯ã§ããªãã
æ·»åæ¼ç®åã¯ãx[y]ã¨ããã¨ãx.operator [] (y)ã®ããã«å¼ã³åºãããã
struct X
{
void operator [] ( int ) ;
} ;
int main()
{
X x ;
x[1] ; // x.operator [] (1)
}
æ·»åæ¼ç®åã«è¤æ°ã®å®å¼æ°ã渡ããã¨ã¯ã§ããªãããã ããåæåãªã¹ããªãã°æ¸¡ããã¨ãã§ããã
struct X
{
void operator [] ( std::initializer_list<int> list ) ;
} ;
int main()
{
X x ;
x[ { 1, 2, 3 } ] ;
}
ã¯ã©ã¹ã¡ã³ãã¼ã¢ã¯ã»ã¹æ¼ç®åã®èå¥åã¯ãoperator ->ã§ãããã¯ã©ã¹ã¡ã³ãã¼ã¢ã¯ã»ã¹æ¼ç®åã¯ä»®å¼æ°ãåããªãéstaticã¡ã³ãã¼é¢æ°ã¨ãã¦å®£è¨ãããéã¡ã³ãã¼é¢æ°ã«ãããã¨ã¯ã§ããªããã¯ã©ã¹ã¡ã³ãã¼ã¢ã¯ã»ã¹æ¼ç®åã¯ãå¾è¿°ããããã«ãå°ãå¤ãã£ãç¹å¾´ãããã
ã¯ã©ã¹ã¡ã³ãã¼ã¢ã¯ã»ã¹æ¼ç®åã¯ãx->mã¨ããã¨ã(x.operator->())->mã®ããã«å¼ã³åºããããã¤ã¾ãããããx.operator->()ã®æ»ãå¤ã®åãã¯ã©ã¹ã¸ã®ãã¤ã³ã¿ã¼ã§ããã°ããã®ã¾ã¾çµã¿è¾¼ã¿ã®ã¯ã©ã¹ã¡ã³ãã¼ã¢ã¯ã»ã¹æ¼ç®åã使ãããããã以å¤ã®å ´åã¯ãæ»ãå¤ã«å¯¾ãã¦ã¯ã©ã¹ã¡ã³ãã¼ã¢ã¯ã»ã¹æ¼ç®åãé©ç¨ãã¦ããããã«ãããã«æ»ãå¤ã®ã¯ã©ã¹ã¡ã³ãã¼ã¢ã¯ã»ã¹æ¼ç®åããããåå¨ããã°ãå¼ã³åºãããã
struct A
{
int member ;
} ;
struct B
{
A a ;
A * operator ->() { return &a ; }
} ;
struct C
{
B b ;
B & operator ->() { return b ; }
} ;
int main()
{
B b ;
b->member ; // (b.operator ->())->member
C c ;
// (c.operator ->())->member
// ããªãã¡ãã®å ´åã以ä¸ã®ããã«å±éãããã
// ((c.operator ->()).operator ->())->member
c->member ;
}
ã¯ã©ã¹Bã¯ã
ã¯ã©ã¹Cã®operator ->ãB &åãè¿ãã¦ãããã¨ã«æ³¨ç®ãlvalueã®Bã«ã¯ã©ã¹ã¡ã³ãã¼ã¢ã¯ã»ã¹æ¼ç®åã§ãã->ã使ããããããã¯ã©ã¹Bã®ã¯ã©ã¹ã¡ã³ãã¼ã¢ã¯ã»ã¹æ¼ç®åãå¼ã°ããã
ã¯ã©ã¹ã¡ã³ãã¼ã¢ã¯ã»ã¹æ¼ç®åã®è©ä¾¡ã®çµæã«å¯¾ããã¯ã©ã¹ã¡ã³ãã¼ã¢ã¯ã»ã¹æ¼ç®åã®å¼ã³åºãã¯ãééãªãè¡ãããããã®ã«ã¼ããæã¡åãã«ã¯ãæçµçã«ã¯ã©ã¹ã¸ã®ãã¤ã³ã¿ã¼ãè¿ããçµã¿è¾¼ã¿ã®ã¯ã©ã¹ã¡ã³ãã¼ã¢ã¯ã»ã¹æ¼ç®åã使ããªããã°ãªããªãã
ãã¡ãããããã¯æ¼ç®åã¨ãã¦ä½¿ç¨ããå ´åã§ãã£ã¦ãæ示çã«é¢æ°ãå¼ã³åºãå ´åã«ã¯ãé常éãããã®é¢æ°ã ããå¼ã°ããããã¡ãããæ»ãå¤ã®åãvoidåã«ãããã¨ãã§ããã
struct X
{
void operator ->() { }
} ;
int main()
{
X x ;
x.operator ->() ; // OK
}
ã¤ã³ã¯ãªã¡ã³ãæ¼ç®åã®èå¥åã¯operator ++ããã¯ãªã¡ã³ãæ¼ç®åã®èå¥åã¯operator --ã§ãããã¤ã³ã¯ãªã¡ã³ãæ¼ç®åã¨ãã¯ãªã¡ã³ãã®æ¼ç®åã¯éstaticã¡ã³ãã¼é¢æ°ã¨ãéã¡ã³ãã¼é¢æ°ã®ä¸¡æ¹ã§å®£è¨ã§ãããã¤ã³ã¯ãªã¡ã³ãæ¼ç®åã¨ãã¯ãªã¡ã³ãæ¼ç®åã¯ãèå¥åã®éããé¤ãã°ãåãããã«åããããã§ã®ãµã³ãã«ã³ã¼ãã¯ãã¤ã³ã¯ãªã¡ã³ãæ¼ç®åã®èå¥åã使ãã
ã¤ã³ã¯ãªã¡ã³ãã¨ãã¯ãªã¡ã³ãã«ã¯ãåç½®ã¨å¾ç½®ã®éããããã
++a ; // åç½®
a++ ; // å¾ç½®
åç½®æ¼ç®åã¯ãéstaticã¡ã³ãã¼é¢æ°ã®å ´åãä»®å¼æ°ãåããªããéã¡ã³ãã¼é¢æ°ã®å ´åã¯ãã²ã¨ã¤ã®ä»®å¼æ°ãåãã
åç½®æ¼ç®åã¯ã++xã¨ããå¼ã«å¯¾ãã¦ãéstaticã¡ã³ãã¼é¢æ°ã®å ´åãx.operator ++ ()ãéã¡ã³ãã¼é¢æ°ã®å ´åãoperator ++( x )ã®ããã«å¼ã³åºãããã
struct X
{ // éstaticã¡ã³ãã¼é¢æ°ã®ä¾
void operator ++ () ;
} ;
struct Y { } ;
// éã¡ã³ãã¼é¢æ°ã®ä¾
void operator ++ ( Y & ) ;
int main()
{
X x ;
++x ; // x.operator ++()
Y y ;
++y ; // operator ++(y)
}
å¾ç½®æ¼ç®åã¯ãéstaticã¡ã³ãã¼é¢æ°ã®å ´åãintåã®å¼æ°ãåããéã¡ã³ãã¼é¢æ°ã®å ´åã¯ãäºã¤ã®ä»®å¼æ°ãåãã第äºä»®å¼æ°ã®åã¯intã§ãªããã°ãªããªããintåã®ä»®å¼æ°ã¯ãåã«åç½®ã¨å¾ç½®ãå¥ã®å®£è¨ã«ããããã®ã¿ã°ã§ããããã以ä¸ã®æå³ã¯ãªããå¼ã¨ãã¦ã¤ã³ã¯ãªã¡ã³ãã¨ãã¯ãªã¡ã³ãã使ãã¨ãå®å¼æ°ã«ã¯0ã渡ãããã
å¾ç½®æ¼ç®åã¯ãx++ã¨ããå¼ã«å¯¾ãã¦ãéstaticã¡ã³ãã¼é¢æ°ã®å ´åãx.operator ++( 0 ), éã¡ã³ãã¼é¢æ°ã®å ´åãoperator ++ ( x, 0 )ã®ããã«å¼ã³åºãããã
struct X
{ // éstaticã¡ã³ãã¼é¢æ°ã®ä¾
void operator ++ (int) ;
} ;
struct Y { } ;
// éã¡ã³ãã¼é¢æ°ã®ä¾
void operator ++ ( Y & , int ) ;
int main()
{
X x ;
x++ ; // x.operator ++( 0 )
Y y ;
y++ ; // operator ++( y, 0 )
}
intãã¿ã°ã¨ãã¦ä½¿ããã®ä»æ§ã¯ãããæ±ãããä¾å¤çãªææ³ã使ããªãã¦ãããã¨ããå©ç¹ãããã®ã§æ¡ç¨ããããããæ示çã«å¼ã³åºããå ´åã¯ãintåã®ä»®å¼æ°ã«å¯¾ãã0以å¤ã®å®å¼æ°ãä¸ãããã¨ãã§ããã
ããã§ã¯ç¢ºä¿é¢æ°ã¨è§£æ¾é¢æ°ã®ãªã¼ãã¼ãã¼ãã«ã¤ãã¦è§£èª¬ãã¦ããã
注æï¼æ¬æ¥ãããã¯ã³ã¢è¨èªã§ã¯ãªãã©ã¤ãã©ãªã§è¦å®ããã¦ãããã¨ãªã®ã§ãæ¬æ¸ã®ç¯çã§ã¯ãªãã®ã ããããã§ã¯èªè
ã®ä¾¿å®ã®ããã宣è¨æ¹æ³ã¨ãããã©ã«ãã®æåã®ãªãã¡ã¬ã³ã¹å®è£
ãæ示ãããã¾ãããµã³ãã«ã³ã¼ãã¯åå²ãã¦æ²è¼ãã¦ãããã確ä¿é¢æ°ã¨è§£æ¾é¢æ°ã¯ããããé¢ä¿ãã¦ããããã¹ã¦ä¸ã¤ã®ã½ã¼ã¹ãã¡ã¤ã«ã«å«ã¾ãããã¨ãæ³å®ãã¦ããããã®ããããããã¼ãã¡ã¤ã«ã®includeã¯æåã®ãµã³ãã«ã³ã¼ãã«ããæ¸ãã¦ããªãã
確ä¿é¢æ°ã®èå¥åã¯operator newã§ããã解æ¾é¢æ°ã®èå¥åã¯operator deleteã§ããããã®é¢æ°ã¯ãåçã¹ãã¬ã¼ã¸ã®ç¢ºä¿ã¨è§£æ¾ãè¡ãã確ä¿é¢æ°ã¨è§£æ¾é¢æ°ãè¡ãã®ã¯ãçã®åçã¹ãã¬ã¼ã¸ã®ç¢ºä¿ã¨è§£æ¾ã§ããããã誤解ãããããã³ã³ã¹ãã©ã¯ã¿ã¼ããã¹ãã©ã¯ã¿ã¼ã®å¼ã³åºãã®è²¬ä»»ã¯æããªãã
確ä¿é¢æ°ã¨è§£æ¾é¢æ°ã®ãªã¼ãã¼ãã¼ãã¯ãã°ãã¼ãã«åå空éããã¯ã©ã¹ã®ã¡ã³ãã¼é¢æ°ã¨ãã¦å®£è¨ãããã°ãã¼ãã«åå空é以å¤ã®åå空éã§å®£è¨ããã¨ã¨ã©ã¼ã¨ãªãã確ä¿é¢æ°ã¨è§£æ¾é¢æ°ãã¦ã¼ã¶ã¼å®ç¾©ãããªãå ´åãå®è£
ã«ãã£ã¦ããã©ã«ãã®æåãè¡ã確ä¿é¢æ°ã¨è§£æ¾é¢æ°ãèªåçã«å®ç¾©ãããã
// ã°ãã¼ãã«åå空é
void* operator new(std::size_t size) ; // OK
namespace NS
{
void* operator new(std::size_t size); // ã¨ã©ã¼ãã°ãã¼ãã«åå空éã§ã¯ãªã
}
struct X
{
void* operator new(std::size_t size) ; // OK
} ;
ã°ãã¼ãã«åå空éã®å®£è¨ã¯ãããã©ã«ãã®ç¢ºä¿é¢æ°ã¨è§£æ¾é¢æ°ã®çæã妨ãããã¯ã©ã¹ã®ã¡ã³ãã¼é¢æ°ã¯ããã®ã¯ã©ã¹ã¨æ´¾çã¯ã©ã¹ã®ç¢ºä¿ã¨è§£æ¾ã«ä½¿ãããã
確ä¿é¢æ°ã«ã¯ãå¹æ(effect)ã¨å¿
é ã®æå(required behavior)ã¨ããã©ã«ãã®æå(default behavior)ãè¦å®ããã¦ããã解æ¾é¢æ°ã«ã¯ãå¹æã¨ããã©ã«ãã®æåãè¦å®ããã¦ãããå¹æã¨ã¯ããã®é¢æ°ãã©ã®ãããªãã¨ã«ä½¿ãããã®ãã¨ããè¦å®ã§ãããå¿
é ã®æåã¨ã¯ããã¨ãã¦ã¼ã¶ã¼å®ç¾©ã®é¢æ°ã§ãã£ã¦ãå¿
ãå®ããªããã°ãªããªãæåã®ãã¨ã§ãããããã©ã«ãã®æåã¨ã¯ãé¢æ°ãã¦ã¼ã¶ã¼å®ç¾©ããã¦ããªãå ´åãå®è£
ã«ãã£ã¦ç¨æãããå®ç¾©ã®æåã§ããã
C++11ã§ã¯ã¹ã¬ããã®æ¦å¿µãå
¥ã£ãã®ã§ã確ä¿é¢æ°ã¨è§£æ¾é¢æ°ã¯ããã¼ã¿ç«¶åãå¼ãèµ·ããã¦ã¯ãªããªãããã®ä¿è¨¼ã¯ãã¦ã¼ã¶ã¼å®ç¾©ã®ç¢ºä¿é¢æ°ã¨è§£æ¾é¢æ°ã«ãè¦æ±ãããã
C++11ã§ã¯ã¢ã©ã¤ã¡ã³ãã®æ¦å¿µãå
¥ã£ãã®ã§ã確ä¿é¢æ°ã®ç¢ºä¿ããã¹ãã¬ã¼ã¸ã¯ãè¦æ±ããããµã¤ãºä»¥ä¸ã®å¤§ããã®ãªãã¸ã§ã¯ããé
ç½®ã§ãããããé©åã«ã¢ã©ã¤ã³ããã¦ããªããã°ãªããªãã
åæ°å½¢ã®ç¢ºä¿é¢æ°
void* operator new(std::size_t size) ;
- å¹æ
-
ãã®ç¢ºä¿é¢æ°ã¯ãnewå¼ããsizeãã¤ãã®ã¹ãã¬ã¼ã¸ã確ä¿ããããã«å¼ã°ããã
- å¿
é ã®æå
-
é©åã«ã¢ã©ã¤ã³ãããã¹ãã¬ã¼ã¸ãæã示ãnullãã¤ã³ã¿ã¼ã§ã¯ãªãå¤ãè¿ãããããã¯ãstd::bad_exceptionãthrowãããã
- ããã©ã«ãã®æå
-
- ã«ã¼ããå®è¡ãããã«ã¼ãã®ä¸ã§ãã¾ãè¦æ±ãããã¹ãã¬ã¼ã¸ã®ç¢ºä¿ã試ã¿ããã¹ãã¬ã¼ã¸ç¢ºä¿ã®æ¹æ³ã¯å®è£
ä¾åã§ããã
- ã¹ãã¬ã¼ã¸ã®ç¢ºä¿ãæåãããªãã°ãã¹ãã¬ã¼ã¸ã¸ã®ãã¤ã³ã¿ã¼ãè¿ããã¹ãã¬ã¼ã¸ã®ç¢ºä¿ãæåããªãã£ãå ´åã§ãç¾å¨ã®new_handlerãnullãã¤ã³ã¿ã¼ã®å ´åãstd::bad_allocãthrowããã
- ç¾å¨ã®new_handlerãnullãã¤ã³ã¿ã¼ä»¥å¤ã®å ´åãç¾å¨ã®new_handlerãå¼ã³åºããå¼ã³åºããè¿ã£ããªãã°ãã«ã¼ããç¶è¡ããã
- ã«ã¼ãã¯ã¹ãã¬ã¼ã¸ã®ç¢ºä¿ãæåããããnew_handlerã®å¼ã³åºããè¿ããªããªãã¾ã§ãç¶ããããã
#include <cstddef>
#include <cstdlib>
#include <new>
void* operator new( std::size_t size )
{
// std::mallocã«å®å¼æ°0ã渡ããå ´åã®æåã¯å®ç¾©ããã¦ããªã
if ( size == 0 ) { size = 1 ; }
while ( true ) // ã«ã¼ããå®è¡ãã
{
// ã«ã¼ãã®ä¸ã§ãè¦æ±ãããã¹ãã¬ã¼ã¸ã®ç¢ºä¿ã試ã¿ã
void * ptr = std::malloc( size ) ;
// ã¹ãã¬ã¼ã¸ã®ç¢ºä¿ãæåãããªãã°
if ( ptr != nullptr )
{ // ã¹ãã¬ã¼ã¸ã¸ã®ãã¤ã³ã¿ã¼ãè¿ã
return ptr ;
}
// ã¹ãã¬ã¼ã¸ã®ç¢ºä¿ãæåããªãã£ãå ´å
std::new_handler handler = std::get_new_handler() ;
if ( handler == nullptr ) // ç¾å¨ã®new_handlerãnullãã¤ã³ã¿ã¼ã®å ´å
{ // std::bad_allocãthrowããã
throw std::bad_alloc() ;
} else // ç¾å¨ã®new_handlerãnullãã¤ã³ã¿ã¼ã§ã¯ãªãå ´å
{ // ç¾å¨ã®new_handlerãå¼ã³åºã
handler( ) ;
}
// ã«ã¼ããç¶è¡ãã
}
}
nothrowçã®åæ°å½¢ã®ç¢ºä¿é¢æ°
void * operator new( std::size_t size, const std::nothrow_t & ) noexcept ;
- å¹æ
-
åé
ã®ç¢ºä¿é¢æ°ã¨åãããã ããã¨ã©ã¼å ±åã¨ãã¦std::bad_allocãthrowãã代ããã«ãnullãã¤ã³ã¿ã¼ãè¿ãã
- å¿
é ã®æå
-
é©åã«ã¢ã©ã¤ã³ãããã¹ãã¬ã¼ã¸ã¸ã®ãã¤ã³ã¿ã¼ãè¿ãããnullãã¤ã³ã¿ã¼ãè¿ãããã®é¢æ°ã®è¿ããã¤ã³ã¿ã¼ãnothrowã§ã¯ãªã確ä¿é¢æ°ãå¼ã³åºãã¦ã¹ãã¬ã¼ã¸ã確ä¿ããå ´åã¨åããã¤ã³ã¿ã¼ãè¿ãã
- ããã©ã«ãã®æå
-
operator new(size)ãå¼ã³åºããå¼ã³åºããé常éãè¿ãã°ããã®æ»ãå¤ãè¿ãããã以å¤ã®å ´åãnullãã¤ã³ã¿ã¼ãè¿ãã
void* operator new( std::size_t size, const std::nothrow_t & ) noexcept
{
try
{ // operator new(size)ãå¼ã³åºã
// å¼ã³åºããé常éãè¿ãã°ããã®æ»ãå¤ãè¿ã
return operator new( size ) ;
}
catch ( ... )
{ // ãã以å¤ã®å ´åãnullãã¤ã³ã¿ã¼ãè¿ãã
return nullptr ;
}
}
åæ°å½¢ã®è§£æ¾é¢æ°
void operator delete( void * ptr ) noexcept ;
- å¹æ
-
ãã®è§£æ¾é¢æ°ã¯ãptrã®å¤ãç¡å¹ã«ãããããdeleteå¼ããå¼ã°ãããptrã®å¤ã¯ãnullãã¤ã³ã¿ã¼ããoperator new(std::size_t) ããã㯠operator new(std::size_t,const std::nothrow_t&)ã«ãã£ã¦è¿ãããå¤ã§ãã¾ã operator delete(void*)ã«æ¸¡ãã¦ããªããã®ã§ããã
- ããã©ã«ãã®æå
-
ptrã®å¤ãnullãã¤ã³ã¿ã¼ã§ããã°ããªã«ãããªãããã以å¤ã®å ´åãå
ã®operator newã®å¼ã³åºãã§ç¢ºä¿ãããã¹ãã¬ã¼ã¸ã解æ¾ããã
void operator delete( void* ptr ) noexcept
{
std::free( ptr ) ;
}
nothrowçã®åæ°å½¢ã®è§£æ¾é¢æ°
void operator delete( void * ptr, const std::nothrow_t & ) noexcept ;
- å¹æ
-
nothrowçã®newå¼ã«ãã£ã¦å¼ã³åºãããã³ã³ã¹ãã©ã¯ã¿ã¼ãä¾å¤ãæããæã«ãã¹ãã¬ã¼ã¸ã解æ¾ããããã«å¼ã°ãããdeleteå¼ã§ã¯å¼ã°ããªãã
struct X
{
X() { throw 0 ; }
} ;
int main()
{
new(std::nothrow) X ; // operator delete( void *, std::nothrow_t &)ãå¼ã°ãã
}
- ããã©ã«ãã®æå
-
operator delete(ptr)ãå¼ã³åºãã
void operator delete( void* ptr, const std::nothrow_t & ) noexcept
{
operator delete( ptr ) ;
}
é
åå½¢ã®ç¢ºä¿é¢æ°
void * operator new[]( std::size_t size ) ;
- å¹æ
-
ãã®ç¢ºä¿é¢æ°ã¯é
åå½¢ã®newå¼ããsizeãã¤ãã®ã¹ãã¬ã¼ã¸ã確ä¿ããããã«å¼ã°ããã
- å¿
é ã®æå
-
åæ°å½¢ã®ç¢ºä¿é¢æ°ã¨åãã
- ããã©ã«ãã®æå
-
operator new(size)ãè¿ãã
void * operator new[]( std::size_t size )
{
return operator new( size ) ;
}
nothrowçã®é
åå½¢ã®ç¢ºä¿é¢æ°
void * operator new[]( std::size_t size, const std::nothrow_t & ) noexcept ;
- å¹æ
-
ãã®ç¢ºä¿é¢æ°ã¯ãnothrowçã®newå¼ããå¼ã°ãããã¨ã©ã¼å ±åã¨ãã¦ãstd::bad_allocãthrowãã代ããã«ãnullãã¤ã³ã¿ã¼ãè¿ãã
- å¿
é ã®æå
-
é©åã«ã¢ã©ã¤ã³ãããã¹ãã¬ã¼ã¸ã¸ã®ãã¤ã³ã¿ã¼ãè¿ãããnullãã¤ã³ã¿ã¼ãè¿ãã
- ããã©ã«ãã®æå
-
operator new[](size)ãå¼ã³åºããå¼ã³åºããé常éãè¿ãã°ããã®çµæãè¿ãããã以å¤ã®å ´åã¯ãnullãã¤ã³ã¿ã¼ãè¿ãã
void * operator new[]( std::size_t size, const std::nothrow_t & ) noexcept
{
try
{
return operator new[]( size ) ;
}
catch ( ... )
{
return nullptr ;
}
}
é
ååã®è§£æ¾é¢æ°
void operator delete[]( void * ptr ) noexcept ;
- å¹æ
-
ãã®è§£æ¾é¢æ°ã¯ãé
ååã®deleteå¼ãããptrã®å¤ãç¡å¹ã«ããããã«å¼ã°ããã
- ããã©ã«ãã®æå
-
operator delete(ptr)ãå¼ã¶ã
void operator delete[]( void * ptr ) noexcept
{
operator delete( ptr ) ;
}
nothrowçã®é
ååã®è§£æ¾é¢æ°
void operator delete[]( void * ptr, const std::nothrow_t & ) noexcept ;
- å¹æ
-
nothrowçã®é
ååã®newå¼ã«ãã£ã¦å¼ã³åºãããã³ã³ã¹ãã©ã¯ã¿ã¼ãä¾å¤ãæããæã«ãã¹ãã¬ã¼ã¸ã解æ¾ããããã«å¼ã°ãããé
ååã®deleteå¼ã§ã¯å¼ã°ããªãã
- ããã©ã«ãã®æå
-
operator delete[](ptr)ãå¼ã³åºãã
void operator delete[]( void * ptr, const std::nothrow_t & ) noexcept
{
operator delete[]( ptr ) ;
}
以ä¸ã®å½¢ã®ãªã¼ãã¼ãã¼ãæ¼ç®åã¯ãã¦ã¼ã¶ã¼å®ç¾©ãªãã©ã«æ¼ç®åã®ãªã¼ãã¼ãã¼ãã§ããã
operator "" èå¥å
""ã¨èå¥åã®éã«ã¯ãå¿
ãã²ã¨ã¤ä»¥ä¸ã®ç©ºç½æåãå
¥ããªããã°ãªããªããã¾ããèå¥åã®å
é æåã¯ãå¿
ãã¢ã³ãã¼ã¹ã³ã¢ã²ã¨ã¤ããå§ã¾ããªããã°ãªããªãããã ããé常ã®èå¥åã§ã¯ãã¢ã³ãã¼ã¹ã³ã¢ããå§ã¾ãååã¯äºç´ããã¦ããã®ã§æ³¨æãããã¨ãããã¯ãã¦ã¼ã¶ã¼å®ç¾©ãªãã©ã«æ¼ç®åã®ã¿ã®ç¹å¥ãªæ¡ä»¶ã§ããã
// OK
void operator "" /* 空ç½æåãå¿
è¦ */ _x( unsigned long long int ) ;
// ã¨ã©ã¼ã""ã¨_yã®éã«ç©ºç½æåããªã
void operator ""_y( unsigned long long int ) ;
// ã¨ã©ã¼ãèå¥åãã¢ã³ãã¼ã¹ã³ã¢ããå§ã¾ã£ã¦ããªã
void operator "" z( unsigned long long int ) ;
// ã¨ã©ã¼ã""ã®éã«ç©ºç½æåããã
void operator " " _z( unsigned long long int ) ;
ãªãã©ã«æ¼ç®åã®ä»®å¼æ°ãªã¹ãã¯ã以ä¸ã®ããããã§ãªããã°ãªããªãã
const char*
unsigned long long int
long double
char
wchar_t
char16_t
char32_t
const char*, std::size_t
const wchar_t*, std::size_t
const char16_t*, std::size_t
const char32_t*, std::size_t
ä¸è¨ä»¥å¤ã®ä»®å¼æ°ãªã¹ããæå®ããã¨ãã¨ã©ã¼ã¨ãªãã
ãªãã©ã«æ¼ç®åãã³ãã¬ã¼ãã¯ãä»®å¼æ°ãªã¹ãã空ã§ããã³ãã¬ã¼ãä»®å¼æ°ã¯ãcharåã®éåãã³ãã¬ã¼ãä»®å¼æ°ã®ä»®å¼æ°ããã¯ã§ãªããã°ãªããªãã
template < char ... Chars >
void operator "" _x () { }
ãã以å¤ã®ãã³ãã¬ã¼ãä»®å¼æ°ãåããªãã©ã«æ¼ç®åãã³ãã¬ã¼ãã¯ã¨ã©ã¼ã¨ãªãã
ãªãã©ã«æ¼ç®åã¯ãCãªã³ã±ã¼ã¸ãæã¤ãã¨ãã§ããªãã
// ã¨ã©ã¼
extern "C" void operator "" _x( unsigned long long int ) { }
// OK
extern "C++" void operator "" _x( unsigned long long int ) { }
ãªãã©ã«æ¼ç®åã¯ãåå空éã¹ã³ã¼ãã§å®£è¨ããªããã°ãªããªããã¤ã¾ããã¯ã©ã¹ã¹ã³ã¼ãã§å®£è¨ãããã¨ã¯ã§ããªãããã ããfriendé¢æ°ã«ãªããã¨ã¯ã§ããã
// ã°ãã¼ãã«åå空éã¹ã³ã¼ã
void operator "" _x( unsigned long long int ) { }
namespace ns {
// nsåå空éã¹ã³ã¼ã
void operator "" _x( unsigned long long int ) { }
}
class X
{
// OKãfriend宣è¨ã§ãã
friend void operator "" _x( unsigned long long int ) ;
// ã¨ã©ã¼ãã¯ã©ã¹ã¹ã³ã¼ãã§ã¯å®£è¨ã§ããªã
static void operator "" _y( unsigned long long int ) ;
} ;
ãã ããåå空éã¹ã³ã¼ãã§å®£è¨ãããªãã©ã«æ¼ç®åããã¦ã¼ã¶ã¼å®ç¾©ãªãã©ã«ã¨ãã¦ä½¿ãã«ã¯ãusing宣è¨ãusingãã£ã¬ã¯ãã£ããå¿
è¦ã¨ãªãã
namespace ns {
void operator "" _x( unsigned long long int ) { }
}
int main( )
{
1_x ; // ã¨ã©ã¼ãoperator "" _xã¯è¦ã¤ãããªã
{
using namespace ns ;
1_x ; // OK
}
{
using ns::operator "" _x ;
1_x ; // OK
}
}
ãã以å¤ã¯ãé常ã®é¢æ°ã¨ä½ãå¤ããªããä¾ãã°ãæ示çã«å¼ã³åºããã¨ãã§ãããããã®éã«ã¯é常ã®ãªã¼ãã¼ãã¼ã解決ã«å¾ããinlineãconstexpré¢æ°ã¨ãã¦å®£è¨ãããã¨ãã§ãããå
é¨ãªã³ã±ã¼ã¸ã§ãå¤é¨ãªã³ã±ã¼ã¸ã®ã©ã¡ãã§ãæã¦ããã¢ãã¬ã¹ãåå¾ã§ãããçã
ã
ä¾å¤(Exception)ã¯ãå®è¡ãä¾å¤ãã³ãã©ã¼ã«ç§»ãæ©è½ã§ãããä¾å¤ã¯ã¹ã¬ãããã¨ã«åå¨ãããå®è¡ãä¾å¤ãã³ãã©ã¼ã«ç§»ãéã«ããªãã¸ã§ã¯ãã渡ããã¨ãã§ãããä¾å¤ãã³ãã©ã¼ã«å®è¡ã移ãã«ã¯ãtryãããã¯ã®ä¸ããtryãããã¯ã®ä¸ã§å¼ã°ãã¦ããé¢æ°ã®ä¸ã§throwå¼ã使ãã
tryãããã¯:
try è¤åæ ãã³ãã©ã¼seq
é¢æ°tryãããã¯:
try ã³ã³ã¹ãã©ã¯ã¿ã¼åæååopt è¤åæ ãã³ãã©ã¼seq
ãã³ãã©ã¼seq:
ãã³ãã©ã¼ ãã³ãã©ã¼seq
ãã³ãã©ã¼:
catch ( ä¾å¤å®£è¨ ) è¤åæ
throwå¼:
throw 代å
¥å¼opt
tryãããã¯æã®ææ³ã¯ããã¼ã¯ã¼ãtryã«ç¶ãã¦è¤åæãæ¸ããã²ã¨ã¤ä»¥ä¸ã®ãã³ãã©ã¼ãè¨è¿°ãããthrowå¼ã®åã¯voidã§ãããthrowå¼ãå®è¡ããã³ã¼ãã®ãã¨ãããä¾å¤ãæãã(throw an exception)ãã³ã¼ãã¨ãããå¦çããã³ãã©ã¼ã«ç§»ãã
int main()
{
try
{
throw 0 ; // intåã®ãªãã¸ã§ã¯ããthrowãã
}
catch ( int i )
{
// intåã®ãªãã¸ã§ã¯ããthrowãããæã«å®è¡ããã
}
catch ( double d )
{
// doubleåã®ãªãã¸ã§ã¯ããthrowãããæã«å®è¡ããã
}
catch ( ... )
{
// ä»»æã®åã®ãªãã¸ã§ã¯ããthrowãããæã«å®è¡ããã
}
}
gotoæãswitchæã使ããtryãããã¯ããã³ãã©ã¼ã®å¤å´ããå
å´ã«å¦çã移ãã¦ã¯ãªããªããtryãããã¯å
ããã³ãã©ã¼å
ã®ç§»åã¯ã§ããã
int main()
{
// ã¨ã©ã¼ãtryãããã¯ã®å¤å´ããå
å´ã«å¦çã移ã
goto begin_try_block ;
// ã¨ã©ã¼ããã³ãã©ã¼ã®å¤å´ããå
å´ã«å¦çã移ã
goto begin_handler ;
try
{
begin_try_block: ;
// OKãtryãããã¯å
ã®ç§»å
goto end_try_block ;
end_try_block: ;
}
catch ( ... )
{
begin_handler: ;
// OKããã³ãã©ã¼å
ã®ç§»å
goto end_handler ;
end_handler: ;
}
}
void f( int i )
{
switch( i )
{
// OK
case 0 : ;
try
{
// ã¨ã©ã¼
case 1 : ;
}
catch ( ... )
{
// ã¨ã©ã¼
case 2 : ;
}
// OK
case 4 : ;
}
}
gotoæãbreakæãreturnæãcontinueæã使ã£ã¦ãtryãããã¯ã¨ãã³ãã©ã¼ã®å
å´ããå¤å´ã«æãããã¨ãã§ããã
void f()
{
try
{
goto end_f ; // OK
}
catch ( ... )
{
return ; // OK
}
end_f : ;
}
é¢æ°tryãããã¯(function-try-block)ã¯ãé¢æ°ã®æ¬ä½ã«è¨è¿°ã§ããã
void f()
try
{
}
catch ( ... )
{
}
ã³ã³ã¹ãã©ã¯ã¿ã¼ã®é¢æ°ã®æ¬ä½ã¨ãã¦è¨è¿°ããå ´åã«ã¯ãtryã¨è¤åæã®éã«ã³ã³ã¹ãã©ã¯ã¿ã¼åæååãè¨è¿°ããã
struct X
{
int m1 ;
int m2 ;
X()
try
: m1(0), m2(0) // ã³ã³ã¹ãã©ã¯ã¿ã¼åæåå
{ }
catch ( ... ) { }
} ;
é¢æ°tryãããã¯ãã³ã³ã¹ãã©ã¯ã¿ã¼ããã¹ãã©ã¯ã¿ã¼ã®æ¬ä½ã«ç¨ããããå ´åãè¤åæã¨ãæ§ç¯ã¨ç ´æ£ã®éã«ã¯ã©ã¹ã®ãµããªãã¸ã§ã¯ããä¾å¤ãæããå ´åããã³ãã©ã¼ã«å¦çã移ãã
ã³ã³ã¹ãã©ã¯ã¿ã¼ã«é¢æ°tryãããã¯ã使ãä¾
// æ§ç¯æã®ä¾å¤ãæããã¯ã©ã¹
struct throw_at_construction
{
throw_at_construction()
{
throw 0 ;
}
} ;
struct X
{
// æ§ç¯æã«ä¾å¤ãæãããã¼ã¿ã¡ã³ãã¼
throw_at_construction member ;
X()
try : member()
{ }
catch ( ... ) { } // ãã³ãã©ã¼ã«å¦çã渡ã
} ;
// æ§ç¯æã«ä¾å¤ãæããåºæ¬ã¯ã©ã¹
struct Y : throw_at_construction
{
Y()
try { }
catch ( ... ) { } // ãã³ãã©ã¼ã«å¦çã渡ã
} ;
ãã¹ãã©ã¯ã¿ã¼ã«é¢æ°tryãããã¯ã使ãä¾
// ç ´æ£æã«ä¾å¤ãæããã¯ã©ã¹
struct throw_at_destruction
{
~throw_at_destruction()
{
throw 0 ;
}
} ;
struct X
{
throw_at_destruction member ;
~X()
try { }
catch ( ... ) { }
} ;
struct Y : throw_at_destruction
{
~Y()
try { }
catch ( ... ) { }
} ;
ä¾å¤ãæãã(throwing an exception)ã¨ã¯ãæ¥æ¬èªã§ã¯ä»ã«ããéåºããã¨ãã¹ãã¼ãããªã©ã¨ãæ¸ããã¦ããã
ä¾å¤ãæããã¨ãå¦çã¯ãã³ãã©ã¼ã«ç§»ããä¾å¤ãæããã¨ãã«ã¯ããªãã¸ã§ã¯ãã渡ãããããªãã¸ã§ã¯ãã®åã«ãã£ã¦ãå¦çã渡ããããã³ãã©ã¼ã決ã¾ãã
// intå
throw 0 ;
// const char *å
throw "hello" ;
struct X { } ;
X x ;
// Xå
throw x ;
ä¾å¤ãæããããã¨ãåãä¸è´ããæãè¿ãå ´æã«ãããã³ãã©ã¼ã«å¦çã移ãããæãè¿ããã¨ããã®ã¯ãæè¿ã«å
¥ã£ã¦ãã¾ã æãã¦ããªãtryãããã¯ã«å¯¾å¿ãããã³ãã©ã¼ã§ããã
// ä¾å¤ãæãã
void f() { throw 0 ; }
int main()
{
try
{
try
{
try { f() } // é¢æ°fã®ä¸ã§ä¾å¤ãæãã
catch ( ... ) { } // ããã«å¦çã移ã
}
catch ( ... ) { }
}
catch ( ... ) { }
}
throwå¼ã¯ãªãã©ã³ãããä¸æãªãã¸ã§ã¯ããåæåããããã®ä¸æãªãã¸ã§ã¯ããä¾å¤ãªãã¸ã§ã¯ã(exception object)ã¨ãããä¾å¤ãªãã¸ã§ã¯ãã®åã決å®ããã«ã¯ãthrowå¼ã®ãªãã©ã³ãã®åãããããã¬ãã«ã®CV修飾åãåãé¤ããTåã¸ã®é
ååã¯Tã¸ã®ãã¤ã³ã¿ã¼åã¸ãTåãè¿ãé¢æ°åã¯ãTåãè¿ãé¢æ°ã¸ã®ãã¤ã³ã¿ã¼åã«å¤æããã
throw 0 ; // int
int const a = 0 ;
throw a ; // int
int const volatile * const volatile p = &a ;
throw p ; // int const volatile *
int b[5] ;
throw b ; // int *
int f( int ) ;
throw f ; // int (*)(int)
ãã®ä¸æãªãã¸ã§ã¯ãã¯lvalueã§ãããåãé©åãããã³ãã©ã¼ã®å¤æ°ã®åæåã«ä½¿ãããã
void f()
{
try
{
throw 0 ; // ä¾å¤ãªãã¸ã§ã¯ãã¯intåã®lvalue
}
catch ( int exception_object ) // ä¾å¤ãªãã¸ã§ã¯ãã§åæåããã
{ }
}
ä¾å¤ãªãã¸ã§ã¯ãã®åãä¸å®å
¨åãä¸å®å
¨åã¸ã®ãã¤ã³ã¿ã¼åã§ããå ´åã¯ãã¨ã©ã¼ã¨ãªãã
struct incomplete_type ;
void f()
{
// ã¨ã©ã¼ãä¸å®å
¨åã¸ã®ãã¤ã³ã¿ã¼å
throw static_cast<incomplete_type *>(nullptr) ;
}
ãã ããvoidåã¯ãã®éãã§ã¯ãªãã
void f()
{
// OKãvoid *
throw static_cast<void *>(nullptr) ;
}
ããã¤ãã®å¶éãé¤ãã°ãthrowå¼ã®ãªãã©ã³ãã¯ãé¢æ°ã¸ã®å®å¼æ°ãreturnæã®ãªãã©ã³ãã¨ã»ã¼åãæ±ãã«ãªã£ã¦ããã
ä¾å¤ãªãã¸ã§ã¯ãã®ã¡ã¢ãªã¼ã¯ãæªè¦å®ã®æ¹æ³ã§ç¢ºä¿ãããã
ä¾å¤ãªãã¸ã§ã¯ãã®å¯¿å½ã®æ±ºå®ã«ã¯ãµãã¤ã®æ¡ä»¶ããããã©ã¡ããé
ãæ¹ã«åããã¦ç ´æ£ãããã
ã²ã¨ã¤ã¯ä¾å¤ãåã³æãã以å¤ã®æ¹æ³ã§ãä¾å¤ãæãããã³ãã©ã¼ããæãåºããã¨ã
void f()
{
try
{
throw 0 ;
}
catch ( ... )
{
// returnæãgotoæãªã©ã§ãã³ãã©ã¼ã®è¤åæã®å¤å´ã«ç§»åããã
// ãããã¯ãã³ãã©ã¼ã®è¤åæãæå¾ã¾ã§å¦çãå°éããã°ãä¾å¤ãªãã¸ã§ã¯ãã¯ç ´æ£ããã
}
}
ä¾å¤ãåã³æããããå ´åã¯ãä¾å¤ãªãã¸ã§ã¯ãã®å¯¿å½ã¯å»¶é·ãããã
void f() ; // ä¾å¤ãæãããããããªãé¢æ°
void g() {
try { f() ; }
catch ( ... )
{
throw ; // ä¾å¤ãåã³æãã
}
}
ãã®å ´åãä¾å¤ãªãã¸ã§ã¯ãã¯ç ´æ£ãããã«ãä¾å¤å¦çãç¶è¡ããã
ããã²ã¨ã¤ã®æ¡ä»¶ã¯ãä¾å¤ãªãã¸ã§ã¯ããåç
§ããæå¾ã®std::exception_ptrãç ´æ£ãããå ´åãããã¯ã©ã¤ãã©ãªã®è©±ã«ãªãã®ã§ãæ¬æ¸ã§ã¯std::exception_ptrã«ã¤ãã¦ã¯è§£èª¬ããªãã
ä¾å¤ãªãã¸ã§ã¯ãã®ã¹ãã¬ã¼ã¸ã解æ¾ãããæ¹æ³ã¯æªè¦å®ã§ããã
ä¾å¤ãªãã¸ã§ã¯ãã®åãã¯ã©ã¹ã§ããå ´åãã¯ã©ã¹ã®ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ãã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã®ã©ã¡ããçæ¹ã¨ããã¹ãã©ã¯ã¿ã¼ã«ã¢ã¯ã»ã¹å¯è½ã§ãªããã°ãªããªãã
以ä¸ã®ãããªã¯ã©ã¹ã¯ãä¾å¤ãªãã¸ã§ã¯ãã¨ãã¦æãããã¨ãã§ããã
// ä¾å¤ãªãã¸ã§ã¯ãã¨ãã¦æããããã¯ã©ã¹
// ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ãã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ããã¹ãã©ã¯ã¿ã¼ã«ã¢ã¯ã»ã¹å¯è½
struct throwable1
{
throwable1( throwable1 const & ) { }
throwable1( throwable1 && ) { }
~throwable1() { }
} ;
// ä¾å¤ãªãã¸ã§ã¯ãã¨ãã¦æããããã¯ã©ã¹
// ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ããã¹ãã©ã¯ã¿ã¼ã«ã¢ã¯ã»ã¹å¯è½
struct throwable2
{
throwable2( throwable2 const & ) { }
throwable2( throwable2 && ) = delete ;
~throwable2() { }
} ;
// ä¾å¤ãªãã¸ã§ã¯ãã¨ãã¦æããããã¯ã©ã¹
// ã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ããã¹ãã©ã¯ã¿ã¼ã«ã¢ã¯ã»ã¹å¯è½
struct throwable3
{
throwable3( throwable3 const & ) = delete ;
throwable3( throwable3 && ) { }
~throwable3() { }
} ;
ä¾å¤ãªãã¸ã§ã¯ãã¨ãã¦æããããã¯ã©ã¹ã®æ¡ä»¶ãæºããã«ã¯ãã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ã¨ã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ãã©ã¡ããçæ¹ã ãã¢ã¯ã»ã¹ã§ããã°ããããã¹ãã©ã¯ã¿ã¼ã«ã¯å¿
ãã¢ã¯ã»ã¹å¯è½ã§ãªããã°ãªããªãã
以ä¸ã®ãããªã¯ã©ã¹ã¯æãããã¨ãã§ããªãã
// ä¾å¤ãªãã¸ã§ã¯ãã¨ãã¦æããããªãã¯ã©ã¹
struct unthrowable
{
// ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ãã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ä¸¡æ¹ã«ã¢ã¯ã»ã¹ã§ããªã
unthrowable( unthrowable const & ) = delete ;
unthrowable( unthrowable && ) = delete ;
// ãã¹ãã©ã¯ã¿ã¼ã«ã¢ã¯ã»ã¹ã§ããªã
~unthrowable() = delete ;
} ;
ãã¨ããã³ãã¼ãã ã¼ããçç¥å¯è½ãªæèã§ããã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ãã ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã®ã©ã¡ããçæ¹ã«ã¯ã¢ã¯ã»ã¹å¯è½ã¨ããæ¡ä»¶ãæºããã¦ããªããã°ãã¯ã©ã¹ã¯ä¾å¤ãªãã¸ã§ã¯ãã¨ãã¦æãããã¨ãã§ããªãã
ä¾å¤ã¯ããããã³ãã©ã¼ã«å¦çã移ã£ã段éã§ãã¨ããããã(ãã£ããããã)ã¨ã¿ãªãããããã ããä¾å¤ãã¨ããããããã³ãã©ã¼ããåã³æããããå ´åã¯ãåã³ã¨ããããã¦ããªãç¶æ
ã«æ»ãã
try
{
throw 0 ;
}
catch ( ... )
{
// ä¾å¤ã¯ã¨ããããã
throw ; // åã³ã¨ããããã¦ããªãç¶æ
ã«æ»ã
}
ä¾å¤ãªãã¸ã§ã¯ãã¨ãã¦æããããåæåå¼ã®è©ä¾¡ãå®äºããå¾ãããä¾å¤ãã¨ãããããã¾ã§ã®éã«ãå¥ã®ä¾å¤ãæããããå ´åã¯ãstd::terminateãå¼ã°ããã
ãããèµ·ããããããç¶æ³ã¯ãã¹ã¿ãã¯ã¢ã³ã¯ã¤ã³ãã£ã³ã°ã®æä¸ã«ãã¹ãã©ã¯ã¿ã¼ããä¾å¤ãæãããããã¨ã ã
// ãã¹ãã©ã¯ã¿ã¼ãä¾å¤ãæããã¯ã©ã¹
struct C
{
// ãã¹ãã©ã¯ã¿ã¼ã«æ示çãªä¾å¤æå®ããªãå ´åããã®æèã§ã¯æé»ã«throw()ã«ãªããã
// ãã¹ãã©ã¯ã¿ã¼ã®å¤ã«ä¾å¤ãæããã«ã¯ä¾å¤æå®ãå¿
è¦
~C() noexcept( false ) { throw 0 ; }
} ;
int main()
{
try
{
C c ;
throw 0 ;
// Cåã®ãªãã¸ã§ã¯ãcãç ´æ£ããã
// ä¾å¤ä¸ã«ä¾å¤ãæãããããããstd::terminateãå¼ã°ãã
}
catch ( ... ) { }
}
ä¸è¬çã«ããã¹ãã©ã¯ã¿ã¼ããä¾å¤ãæããã¹ãã§ã¯ãªãã
åæåå¼ã®è©ä¾¡ãå®äºããå¾ã¨ããç¹ã«æ³¨æãthrowå¼ã®ãªãã©ã³ãã®åæåå¼ã®è©ä¾¡ä¸ã®ä¾å¤ã¯ãã®æ¡ä»¶ã«å½ã¦ã¯ã¾ããªãã
struct X
{
X() { throw 0 ; }
} ;
int main( )
{
try
{
// OKãåæåå¼ã®è©ä¾¡ä¸ã®ä¾å¤
// ä¾å¤ãªãã¸ã§ã¯ãã®åã¯int
throw X() ;
}
catch ( X & exception ) { }
catch ( int exception ) { } // ãã®ãã³ãã©ã¼ã§ã¨ããããã
}
ãã®ä¾ã§ã¯Xåã®ãªãã¸ã§ã¯ããä¾å¤ã¨ãã¦throwããåã«ãåæåä¸ã«intåã®ä¾å¤ãæããããã®ã§ãçµæã¨ãã¦æããããä¾å¤ãªãã¸ã§ã¯ãã®åã¯intåã«ãªãã
ãã ããåæåå¼ã®è©ä¾¡ãå®äºããå¾ã¨ããç¹ã«æ³¨æãåæåå®äºã®å¾ã«ä¾å¤ãæããããå ´åã¯ãstd::terminateãå¼ã°ããã
// ãã®ä¾ãstd::terminateãå¼ã¶ãã©ããã¯ãC++ã®å®è£
次第ã§ããã
struct X
{
X( X const & ) { throw 0 ; }
} ;
int main( )
{
try
{
// å®è£
ãã³ãã¼ãçç¥ããªãå ´åãstd::terminateãå¼ã°ãã
// ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ã®å®è¡ã¯è©ä¾¡å®äºå¾
throw X() ;
}
catch ( ... ) { }
}
ãã®æèã§ã¯ãè³¢ãC++ã®å®è£
ãªãã°ãã³ãã¼ãçç¥ã§ããããã ããã³ãã¼ãçç¥ãããä¿è¨¼ã¯ãªãããããä¾å¤ãªãã¸ã§ã¯ããæ§ç¯ããéã«ã³ãã¼ãè¡ããããªãã°ãããã¯throwå¼ã®ãªãã©ã³ãã®åæåå¼ã®è©ä¾¡å®äºå¾ãªã®ã§ããã®æ¡ä»¶ã«å½ã¦ã¯ã¾ããstd::terminateãå¼ã°ããã
ã¾ããç¾è¡ã®è¦æ ¼ã®æé¢ã«ã¯èª¤ããããã以ä¸ã®ã³ã¼ãã§ã¯std::terminateãå¼ã°ãããã解éã§ãã¦ãã¾ãã
// ä¾å¤ã«ãã£ã¦æãåºãé¢æ°
void f() { throw 0 ; }
struct C
{
~C()
{
// ä¾å¤ã«ãã£ã¦æãåºãé¢æ°ãå¼ã¶
try { f() ; }
catch ( ... ) { }
}
} ;
int main()
{
try
{
C c ;
throw 0 ;
// ä¾å¤ããã³ãã©ã¼ã«ã¨ãããããåã«ãcã®ãã¹ãã©ã¯ã¿ã¼ãå¼ã°ãã
}
catch ( ... ) { }
}
ããã¯è¦æ ¼ã®èª¤ãã§ãããæ¬æ¸å·çã®æç¹ã§ãä¿®æ£ãæ¤è¨ããã¦ããã
ãªãã©ã³ãã®ãªãthrowå¼ã¯ãç¾å¨ã¨ããããã¦ããä¾å¤ãåã³æãã(rethrow)ãããã¯ãåéåºã¨ããªã¹ãã¼ãªã©ã¨ãå¼ã°ãã¦ãããä¾å¤ãåã³æå¹ã«ãªããä¾å¤ãªãã¸ã§ã¯ãã¯ç ´æ£ãããã«åå©ç¨ããããã¤ã¾ããä¾å¤ããµããã³æããéã«ä¸æãªãã¸ã§ã¯ããæ°ãã«ä½ããã¨ã¯ãªããä¾å¤ã¯åã³ã¨ããããã¦ãããã®ã¨ã¯ã¿ãªãããªããªããstd::uncaught_exception()ã®å¤ããã¾ãtrueã«ãªãã
int main()
{
try
{
try
{
throw 0 ;
}
catch ( int e )
{ // ä¾å¤ãã¨ããã
throw ; // ä¸åº¦æããä¾å¤ãåã³æãã
}
}
catch ( int e )
{
// åã³æããããä¾å¤ãã¨ããã
}
}
ä¾å¤ãã¨ããããã¦ããªãç¶æ
ã§ãªãã©ã³ãã®ãªãthrowå¼ãå®è¡ããã¨ãstd::terminateãå¼ã°ããã
int main()
{
throw ; // std::terminateãå¼ã°ãã
}
å¦çãthrowå¼ãããã³ãã©ã¼ã«ç§»ãã«ããã£ã¦ãtryãããã¯ã®ä¸ã§æ§ç¯ãããèªåãªãã¸ã§ã¯ãã®ãã¹ãã©ã¯ã¿ã¼ãå¼ã³åºããããèªåãªãã¸ã§ã¯ãã®ç ´æ£ã¯æ§ç¯ã®éé ã«è¡ãããã
struct X
{
X() { }
~X() { }
} ;
int main()
{
try
{
X a ;
X b ;
X c ;
// a, b, cã®é ã«æ§ç¯ããã
throw 0 ;
}
// ãã®ãã³ãã©ã¼ã«å¦çã移ãéç¨ã§ã
// c, b, aã®é ã«ç ´æ£ããã
catch ( int ) { }
}
ãªãã¸ã§ã¯ãã®æ§ç¯ãç ´æ£ããä¾å¤ã«ããä¸æãããå ´åãå®å
¨ã«æ§ç¯ããããµããªãã¸ã§ã¯ãã«å¯¾ãã¦ãã¹ãã©ã¯ã¿ã¼ãå®è¡ãããããªãã¸ã§ã¯ããæ§ç¯ãããã¹ãã¬ã¼ã¸ã®ç¨®é¡ã¯åããªãã
struct Base
{
Base() { }
~Base() { }
} ;
// ã³ã³ã¹ãã©ã¯ã¿ã¼ã«å®å¼æ°trueã渡ãããå ´åãä¾å¤ãæããã¯ã©ã¹
struct Member
{
Member( bool b )
{
if ( b )
throw 0 ;
}
~Member() { }
} ;
// Xã®ãµããªãã¸ã§ã¯ãã¯ãåºæ¬ã¯ã©ã¹Baseã¨ãéstaticãã¼ã¿ã¡ã³ãã¼ãa, b, c
struct X : Base
{
Member a, b, c ;
X() : a(false), b(true), c(false)
{ }
// Base, aã®ãã¹ãã©ã¯ã¿ã¼ãå®è¡ãããã
~X() { }
} ;
int main()
{
try
{
X x ;
}
catch ( int ) { }
}
ãã®ä¾ã§ã¯ãã¯ã©ã¹Xã¯ããµããªãã¸ã§ã¯ãã¨ãã¦ãBaseåã®åºæ¬ã¯ã©ã¹ã¨ãMemberåã®éstaticãã¼ã¿ã¡ã³ãã¼ãa, b, cãæã¤ããã®åæåé åºã¯ãåºæ¬ã¯ã©ã¹Base, a, b, c, Xã§ãããã¯ã©ã¹Memberã¯ãã³ã³ã¹ãã©ã¯ã¿ã¼ã®å®å¼æ°ã«trueã渡ãããå ´åãä¾å¤ãæãããã¯ã©ã¹Xã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ãbã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã«trueãä¸ãã¦ããããã®çµæãã¯ã©ã¹Xã®ãªãã¸ã§ã¯ãã®æ§ç¯ã¯ãä¾å¤ã«ãã£ã¦ä¸æãããã
ãã®æããã¹ãã©ã¯ã¿ã¼ãå®è¡ãããã®ã¯ãåºæ¬ã¯ã©ã¹Baseã®ãªãã¸ã§ã¯ãã¨ãMemberåã®éstaticãã¼ã¿ã¡ã³ãã¼aã®ãªãã¸ã§ã¯ãã§ãããbã¯ãã³ã³ã¹ãã©ã¯ã¿ã¼ãä¾å¤ã«ãã£ã¦æãã ãããããæ§ç¯ãå®äºãã¦ããªããcã¯ãã¾ã ã³ã³ã¹ãã©ã¯ã¿ã¼ãå®è¡ããã¦ããªããããæ§ç¯ãå®äºãã¦ããªãããã®ãããb, cã®ãªãã¸ã§ã¯ãã«å¯¾ãã¦ãã¹ãã©ã¯ã¿ã¼ã¯å®è¡ãããªãã
ãã ããunion風ã¯ã©ã¹ã®variantã¡ã³ãã¼ã«ã¯ããã¹ãã©ã¯ã¿ã¼ã¯å¼ã³åºãããªãã
struct Member
{
Member() { }
~Member() { }
} ;
struct X
{
union { Member m ; } ;
X() { throw 0 ; } // mã®ãã¹ãã©ã¯ã¿ã¼ã¯å®è¡ãããªã
~X() { }
} ;
ãããªãã¸ã§ã¯ãã®éããªã²ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã®å®è¡ãå®äºãããã®éããªã²ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ãå¼ã³åºããããªã²ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ãä¾å¤ã«ãã£ã¦æãã ããå ´åããã®ãªãã¸ã§ã¯ãã«å¯¾ãã¦ãã¹ãã©ã¯ã¿ã¼ãå¼ã°ããã
struct X
{
// éããªã²ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼
X( bool ) { }
// ããªã²ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼
X() : X( true )
{
throw 0 ; // Xã®ãã¹ãã©ã¯ã¿ã¼ãå¼ã°ãã
}
~X() { }
} ;
ããã¯ããªãã¸ã§ã¯ãã®æ§ç¯å®äºã¯ãéããªã²ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã®å®è¡ãå®äºããæç¹ã ããã ã
ä¾å¤ã«ãã£ã¦æ§ç¯ãä¸æããããªãã¸ã§ã¯ããnewå¼ã«ãã£ã¦æ§ç¯ãããå ´åã使ããã確ä¿é¢æ°ã«å¯¾å¿ãã解æ¾é¢æ°ãããã°ãã¹ãã¬ã¼ã¸ã解æ¾ããããã«èªåçã«å¼ã°ããã
struct X
{
X() { throw 0 ; }
~X() { }
// 確ä¿é¢æ°
void * operator new( std::size_t size ) noexcept
{
return std::malloc( size ) ;
}
// ä¸è¨ç¢ºä¿é¢æ°ã«å¯¾å¿ãã解æ¾é¢æ°
void operator delete( void * ptr ) noexcept
{
std::free( ptr ) ;
}
} ;
int main()
{
try
{
new X ; // 対å¿ãã解æ¾é¢æ°ãå¼ã°ãã
}
catch ( int ) { }
}
ãã®ä¾ã§ã¯ãXãæ§ç¯ããããã«mallocã§ç¢ºä¿ãããã¹ãã¬ã¼ã¸ã¯ãæ£ããfreeã§è§£æ¾ãããã
throwå¼ããå¦çã移ããã³ãã©ã¼ã¾ã§ã®tryãããã¯å
ã®èªåã¹ãã¬ã¼ã¸ä¸ã®ãªãã¸ã§ã¯ãã®ãã¹ãã©ã¯ã¿ã¼ãèªåçã«å¼ã¶ãã®ä¸é£ã®éç¨ã¯ãã¹ã¿ãã¯ã¢ã³ã¯ã¤ã³ãã£ã³ã°(stack unwinding)ã¨å¼ã°ãã¦ããããããã¹ã¿ãã¯ã¢ã³ã¯ã¤ã³ãã£ã³ã°ä¸ã«å¼ã°ãããã¹ãã©ã¯ã¿ã¼ãä¾å¤ã«ãã£ã¦æãã ããå ´åãstd::terminateãå¼ã°ããã
struct X
{
X() { }
~X() noexcept(false)
{
throw 0 ;
}
} ;
int main()
{
try
{
X x ;
throw 0 ; // std::terminateãå¼ã°ãã
}
catch ( int ) { }
}
ç¾è¡ã®æé¢ã解éããã¨ã以ä¸ã®ã³ã¼ããstd::terminateãå¼ã¶ããã«è§£éã§ããããããã¯èª¤ãã§ãããå°æ¥ã®è¦æ ¼æ¹å®ã§ä¿®æ£ãããã¯ãã§ããã
struct Y
{
Y() { }
~Y() noexcept(false) { throw 0 ; }
} ;
struct X
{
X() { }
~X() noexcept(false)
{
try
{
// ã¹ã¿ãã¯ã¢ã³ã¯ã¤ã³ãã£ã³ã°ä¸ã«å¼ã°ãããã¹ãã©ã¯ã¿ã¼ãä¾å¤ã«ãã£ã¦æãåºã
// ç¾è¡ã®è¦æ ¼ã®æé¢è§£éã§ã¯std::terminateãå¼ã°ãã¦ãã¾ã
Y y ;
}
catch ( int ) { }
}
} ;
int main()
{
try
{
X x ;
throw 0 ;
}
catch ( int ) { }
}
ä¸è¬ã«ããã¹ãã©ã¯ã¿ã¼ãä¾å¤ã«ãã£ã¦æãåºããããªã³ã¼ãã¯æ¸ãã¹ãã§ã¯ãªãããã¹ãã©ã¯ã¿ã¼ã¯ã¹ã¿ãã¯ã¢ã³ã¯ã¤ã³ãã£ã³ã°ã®ããã«å¼ã°ãããããããªãããã ãã¹ã¿ãã¯ã¢ã³ã¯ã¤ã³ãã£ã³ã°ä¸ãã©ããã調ã¹ããstd::uncaught_exceptionã®ãããªæ¨æºã©ã¤ãã©ãªãããã«ã¯ããããã¹ã¿ãã¯ã¢ã³ã¯ã¤ã³ãã£ã³ã°ä¸ãã©ããã調ã¹ãå¿
è¦ã¯ãé常ã¯ãªãã
C++11ããã¯ããã¹ãã©ã¯ã¿ã¼ã¯ããã©ã«ãã§ä¾å¤æå®ãã¤ãããã«ãªããã»ã¨ãã©ã®å ´åãnoexcept(true)ã¨äºææ§ã®ããä¾å¤æå®ã«ãªãå¤æ´ããªãããã®ããé常ã¯ãã¹ãã©ã¯ã¿ã¼ãä¾å¤ã§æãåºãå¿
è¦ããªãããã¾ããããã¹ãã§ã¯ãªãããã ã
throwå¼ã«ãã£ã¦æããããä¾å¤ã¯ãtryãããã¯ã®ãã³ãã©ã¼ã«ãã£ã¦ææãããããã³ãã©ã¼ã®ææ³ã¯ä»¥ä¸ã®éãã
catch ( ä¾å¤å®£è¨ ) è¤åæ
int main()
{
try
{
throw 0 ; // ä¾å¤ãªãã¸ã§ã¯ãã®åã¯int
}
catch ( double d ) { }
catch ( float f ) { }
catch ( int i ) { } // ãã®ãã³ãã©ã¼ã«å¦çã移ã
}
ä¾å¤ãæããããã¨ãå¦çã¯ãä¾å¤ãªãã¸ã§ã¯ãã®åã¨é©å(match)ããä¾å¤å®£è¨ãæã¤ãã³ãã©ã¼ã«ç§»ãããã
ãã³ãã©ã¼ã®ä¾å¤å®£è¨ã¯ãä¸å®å
¨åãæ½è±¡ã¯ã©ã¹åãrvalueãªãã¡ã¬ã³ã¹åã§ãã£ã¦ã¯ãªããªãã
struct incomplete ; // ä¸å®å
¨å
struct abstract
{
void f() = 0 ;
} ;
int main()
{
try { }
catch ( incomplete x ) { } // ã¨ã©ã¼ãä¸å®å
¨å
catch ( abstract a ) { } // ã¨ã©ã¼ãæ½è±¡ã¯ã©ã¹å
catch ( abstract * a ) { } // OKãæ½è±¡ã¯ã©ã¹ã¸ã®ãã¤ã³ã¿ã¼å
catch ( abstract & a ) { } // OKãæ½è±¡ã¯ã©ã¹ã¸ã®ãªãã¡ã¬ã³ã¹å
catch ( int && rref) { } // ã¨ã©ã¼ãrvalueãªãã¡ã¬ã³ã¹å
}
ã¾ããä¾å¤å®£è¨ã®åã¯ãä¸å®å
¨åã¸ã®ãã¤ã³ã¿ã¼ããªãã¡ã¬ã³ã¹ã§ãã£ã¦ã¯ãªããªãããã ããvoid *, const void *, volatile void *, const volatile void *ã¯ãä¸å®å
¨åã¸ã®ãã¤ã³ã¿ã¼åã ããä¾å¤çã«è¨±å¯ããã¦ããã
ãã³ãã©ã¼ã®ä¾å¤å®£è¨ããTã¸ã®é
åãã®å ´åããTã¸ã®ãã¤ã³ã¿ã¼ãåã«å¤æãããããTãè¿ãé¢æ°ãåã¯ããTãè¿ãé¢æ°ã¸ã®ãã¤ã³ã¿ã¼ãåã«å¤æãããã
catch ( int [5] ) // int *ã¨åã
catch ( int f( void ) ) // int (*f)(void)ã¨åã
ãããã³ãã©ã¼ããä¾å¤ãªãã¸ã§ã¯ãã®åEã¨é©åããæ¡ä»¶ã¯ä»¥ä¸ã®éãã
-
ãã³ãã©ã¼ã®åã cv Tããã㯠cv T &ã§ãEã¨Tãåãåã§ããå ´åã
cvã¯ä»»æã®CV修飾å(const, volatile)ã®ãã¨ã§ããããã¬ãã«ã®CV修飾åã¯ç¡è¦ãããã
ãã¨ãã°ãä¾å¤ãªãã¸ã§ã¯ãã®åãintã®å ´åã以ä¸ã®ãããªãã³ãã©ã¼ãé©åããã
catch ( int )
catch ( const int )
catch ( volatile int )
catch ( const volatile int )
catch ( int & )
catch ( const int & )
catch ( volatile int & )
catch ( const volatile int & )
-
ãã³ãã©ã¼ã®åãcv Tãcv T &ã§ãTã¯Eã®ææ§æ§ã®ãªãpublicãªåºæ¬ã¯ã©ã¹ã§ããå ´å
ä¾ãã°ã以ä¸ã®ãããªä¾ãé©åããã
struct Base { } ;
struct Derived : public Base { } ;
int main()
{
try
{
Derived d ;
throw d ; // ä¾å¤ãªãã¸ã§ã¯ãã®åã¯Derived
}
catch ( Base & ) { } // é©åãBaseã¯Derivedã®ææ§æ§ã®ãªãpublicãªåºæ¬ã¯ã©ã¹
}
以ä¸ã®ãããªä¾ã¯é©åããªãã
struct Base { } ;
struct Ambiguous { } ;
struct Derived : private Base, public Ambiguous { } ;
struct Sub : public Derived, public Ambiguous { } ;
int main()
{
try
{
Sub sub ;
throw sub ; // ä¾å¤ãªãã¸ã§ã¯ãã®åã¯Sub
}
catch ( Base & ) { } // é©åããªããépublicåºæ¬ã¯ã©ã¹
catch ( Ambiguous & ) { } // é©åããªããææ§
}
-
ãã³ãã©ã¼ã®åãcv1 T* cv2ã§ãEããã¤ã³ã¿ã¼åã§ã以ä¸ã®ããããã®æ¹æ³ã§ãã³ãã©ã¼ã®åã«å¤æå¯è½ãªå ´å
-
æ¨æºãã¤ã³ã¿ã¼åå¤æã§ãprivateãprotectedãªãã¤ã³ã¿ã¼ã¸ã®å¤æããææ§ãªã¯ã©ã¹ã¸ã®å¤æãä¼´ããªããã®
struct Base { } ;
struct Derived : public Base { } ;
int main()
{
try
{
Derived d ;
throw &d ; // ä¾å¤ãªãã¸ã§ã¯ãã®åã¯Derived
}
catch ( Base * ) { } // é©åãBaseã¯Derivedã®ææ§æ§ã®ãªãpublicãªåºæ¬ã¯ã©ã¹
}
-
修飾å¤æ
int main()
{
int i ;
try
{
throw &i ;
}
catch ( const int * ) { }
}
-
ãã³ãã©ã¼ã®åããã¤ã³ã¿ã¼ãã¡ã³ãã¼ã¸ã®ãã¤ã³ã¿ã¼ã§ãEãstd::nullptr_tã®å ´å
struct X
{
int member ;
} ;
int main()
{
try
{
throw nullptr ;
}
catch ( void * ) { } // é©å
catch ( int * ) { } // é©å
catch ( X * ) { } // é©å
catch ( int X::* ) { } // é©å
}
nullptrã®åã§ããstd::nullptr_tåã®ä¾å¤ãªãã¸ã§ã¯ãã¯ããããããã¤ã³ã¿ã¼åãã¡ã³ãã¼ã¸ã®ãã¤ã³ã¿ã¼åã«é©åããã
throwå¼ã®ãªãã©ã³ããå®æ°å¼ã§0ã¨è©ä¾¡ãããå ´åã§ãããã¤ã³ã¿ã¼ãã¡ã³ãã¼ã¸ã®ãã¤ã³ã¿ã¼åã®ãã³ãã©ã¼ã«ã¯é©åããªãã
int main()
{
try
{
throw 0 ; // ä¾å¤ãªãã¸ã§ã¯ãã®åã¯int
}
catch ( int * ) { } // é©åããªã
}
tryãããã¯ã®ãã³ãã©ã¼ã¯ãæ¸ããã¦ããé çªã«æ¯è¼ãããã
int main()
{
try
{
throw 0 ; // ä¾å¤ãªãã¸ã§ã¯ãã®åã¯int
}
catch ( int ) { } // é©åãããå¦çã¯ãã®ãã³ãã©ã¼ã«ç§»ã
catch ( const int ) { }
catch ( int & ) { }
}
ãã®ä¾ã§ã¯ã3ã¤ã®ãã³ãã©ã¼ã¯ã©ããä¾å¤ãªãã¸ã§ã¯ãã®åã«é©åããããæ¯è¼ã¯æ¸ããã¦ããé çªã«è¡ããããä¸çªåãã«é©åãããã³ãã©ã¼ã«å¦çã移ããé¢æ°ã®ãªã¼ãã¼ãã¼ã解決ã®ãããªããã³ãã©ã¼å士ã®åã®é©åã®åªå£ã®æ¯è¼ã¯è¡ãããªãã
ãã³ãã©ã¼ã®ä¾å¤å®£è¨ã«...ã使ãããå ´åããã®ãã³ãã©ã¼ã¯ã©ã®ä¾å¤ã«ãé©åããã
void f()
{
try { }
catch ( int ) { }
catch ( double ) { }
catch ( ... ) { } // ã©ã®ä¾å¤ã«ãé©åãã
}
...ãã³ãã©ã¼ã使ãå ´åã¯ãtryãããã¯ã®ãã³ãã©ã¼ã®æå¾ã«è¨è¿°ããªããã°ãªããªãã
void f()
{
try { }
catch ( ... ) { }
catch ( int ) { } // ã¨ã©ã¼
}
tryãããã¯ã®ãã³ãã©ã¼ã®ãã¡ã«ãé©åãããã³ãã©ã¼ãè¦ã¤ãããªãå ´åãåãã¹ã¬ããå
ã§ããã®tryãããã¯ã®ã²ã¨ã¤ä¸ã®tryãããã¯ã試ã¿ãããã
void f()
{
try { throw 0 ; } // ä¾å¤ãªãã¸ã§ã¯ãã®åã¯int
catch ( double ) { } // é©åããªã
}
void g()
{
try
{
f() ;
}
catch ( int ) { } // é©åãã
}
int main()
{
try
{
g() ;
}
catch ( ... ) { }
}
catchå¥ã®ä»®å¼æ°ã®åæåãå®äºããæç¹ã§ããã³ãã©ã¼ã¯ã¢ã¯ãã£ã(active)ã«ãªã£ãã¨ã¿ãªããããã¹ã¿ãã¯ã¯ãã®æç¹ã§ã¢ã³ã¯ã¤ã³ãããã¦ãããä¾å¤ãæããçµæãstd::terminateãstd::unexpectedãå¼ã°ããå ´åãæé»ã®ãã³ãã©ã¼ã¨ãããã®ãã¢ã¯ãã£ãã«ãªã£ããã®ã¨ã¿ãªããããcatchå¥ããæãã ããå ´åããã³ãã©ã¼ã¯ã¢ã¯ãã£ãã§ã¯ãªããªãã
ç¾å¨ãã¢ã¯ãã£ããªãã³ãã©ã¼ãåå¨ããå ´åãç´åã«æããããä¾å¤ããç¾å¨ææããã¦ããä¾å¤(currently handled exception)ã¨å¼ã¶ã
é©åãããã³ãã©ã¼ãè¦ã¤ãããªãå ´åãstd::terminateãå¼ã°ãããstd::terminateãå¼ã°ããéãã¹ã¿ãã¯ãã¢ã³ã¯ã¤ã³ãããããã©ããã¯å®è£
次第ã§ããã
ã³ã³ã¹ãã©ã¯ã¿ã¼ã¨ãã¹ãã©ã¯ã¿ã¼ã®é¢æ°tryãããã¯ã®ãã³ãã©ã¼å
ã§ãéstaticãã¼ã¿ã¡ã³ãã¼ããªãã¸ã§ã¯ãã®åºæ¬ã¯ã©ã¹ãåç
§ããå ´åãæåã¯æªå®ç¾©ã§ããã
struct S
{
int member ;
S()
try
{
throw 0 ;
}
catch ( ... )
{
int x = member ; // æåã¯æªå®ç¾©
}
} ;
ã³ã³ã¹ãã©ã¯ã¿ã¼ã®é¢æ°tryãããã¯ã®ãã³ãã©ã¼ã«å¦çã移ãåã«ãå®å
¨ã«æ§ç¯ãããåºæ¬ã¯ã©ã¹ã¨éstaticã¡ã³ãã¼ã®ãªãã¸ã§ã¯ãã¯ãç ´æ£ãããã
struct Base
{
Base() { }
~Base() { }
} ;
struct Derived : Base
{
Derived()
try
{
throw 0 ;
}
catch ( ... )
{
// åºæ¬ã¯ã©ã¹Baseã®ãªãã¸ã§ã¯ãã¯ãã§ã«ç ´æ£ããã¦ãã
// éstaticãã¼ã¿ã¡ã³ãã¼ã®ãªãã¸ã§ã¯ãã«ã¤ãã¦ãåæ§
}
} ;
ãªãã¸ã§ã¯ãã®éããªã²ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã®å®è¡ãå®äºãããã¨ã«ãããªã²ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ãä¾å¤ãæããå ´åã¯ããªãã¸ã§ã¯ãã®ãã¹ãã©ã¯ã¿ã¼ãå®è¡ããããã¨ã«ãé¢æ°tryãããã¯ã®ãã³ãã©ã¼ã«å¦çã移ãã
struct S
{
// éããªã²ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼
S() { }
// ããªã²ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼
S( int ) try
: S()
{ throw 0 ; }
catch ( ... )
{
// ãã¹ãã©ã¯ã¿ã¼S::~Sã¯ãã§ã«å®è¡ããã¦ãã
}
~S() { }
} ;
int main()
{
S s(0) ;
}
éããªã²ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ã®å®è¡å®äºããã£ã¦ããªãã¸ã§ã¯ãã¯æ§ç¯ããã¦ãããããªã²ã¼ãã³ã³ã¹ãã©ã¯ã¿ã¼ãä¾å¤ãæããå ´åã®é¢æ°tryãããã¯ã®ãã³ãã©ã¼ã«å¦çã移ãåã«ããªãã¸ã§ã¯ããç ´æ£ãããªããã°ãªããªãããã®ããã«ããã³ãã©ã¼ã«å¦çã移ãåã«ãã¹ãã©ã¯ã¿ã¼ãå¼ã³åºããããã¨ã«ãªãã
ãã¹ãã©ã¯ã¿ã¼ã®é¢æ°tryãããã¯ã®ãã³ãã©ã¼ã«å¦çã移ãåã«ããªãã¸ã§ã¯ãã®åºæ¬ã¯ã©ã¹ã¨évariantã¡ã³ãã¼ã¯ç ´æ£ãããã
struct Base
{
Base() { }
~Base() { }
} ;
struct Derived : Base
{
~Derived() noexcept(false)
try { throw 0 ; }
catch ( ... )
{
// åºæ¬ã¯ã©ã¹ã¯ãã§ã«ç ´æ£ããã¦ãã
// éstaticãã¼ã¿ã¡ã³ãã¼ã«ã¤ãã¦ãåæ§
}
} ;
é¢æ°ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã®ä»®å¼æ°ã®ã¹ã³ã¼ãã¨å¯¿å½ã¯ãé¢æ°tryãããã¯ã®ãã³ãã©ã¼å
ã¾ã§å»¶é·ãããã
void f( int param )
try
{
throw 0 ;
}
catch ( ... )
{
int x = param ; // OKã延é·ããã
}
éçã¹ãã¬ã¼ã¸ä¸ã®ãªãã¸ã§ã¯ãã®ãã¹ãã©ã¯ã¿ã¼ããæããããä¾å¤ããmainé¢æ°ã®é¢æ°tryãããã¯ã®ãã³ãã©ã¼ã§ææããããã¨ã¯ãªããthreadã¹ãã¬ã¼ã¸ä¸ã®ãªãã¸ã§ã¯ãã®ãã¹ãã©ã¯ã¿ã¼ããæããããä¾å¤ããã¹ã¬ããã®åæé¢æ°ã®é¢æ°tryãããã¯ã®ãã³ãã©ã¼ã§ææããããã¨ã¯ãªãã
ã³ã³ã¹ãã©ã¯ã¿ã¼ã®é¢æ°tryãããã¯ã®ãã³ãã©ã¼ã®ä¸ã«returnæãããå ´åãã¨ã©ã¼ã¨ãªãã
struct S
{
S()
try { }
catch ( ... )
{
return ; // ã¨ã©ã¼
}
} ;
ã³ã³ã¹ãã©ã¯ã¿ã¼ã¨ãã¹ãã©ã¯ã¿ã¼ã®é¢æ°tryãããã¯ã§ãå¦çããã³ãã©ã¼ã®çµããã«éããã¨ãã¯ãç¾å¨ãã³ãã«ããã¦ããä¾å¤ããåã³throwãããã
struct S
{
S()
try
{
throw 0 ;
}
catch ( int )
{
// ä¾å¤ãåã³throwããã
}
} ;
ã³ã³ã¹ãã©ã¯ã¿ã¼ã¨ãã¹ãã©ã¯ã¿ã¼ä»¥å¤ã®é¢æ°ã®é¢æ°tryãããã¯ãå¦çããã³ãã©ã¼ã®çµããã«éããã¨ãã¯ãé¢æ°ããreturnããããã®returnã¯ããªãã©ã³ããªãã®returnæã¨åçã«ãªãã
void f()
try
{
throw 0 ;
}
catch ( int )
{
// return ;ã¨åç
}
ãããã®å ´åã«ãé¢æ°ãæ»ãå¤ãè¿ãé¢æ°ã®å ´åãæåã¯æªå®ç¾©ã§ããã
int f()
try
{
throw 0 ;
}
catch ( ... )
{
// æåã¯æªå®ç¾©
}
ä¾å¤å®£è¨ãä¾å¤ã®åã¨ååãæå®ããå ´åãä¾å¤ã®åã®ãªãã¸ã§ã¯ãããã®ååã§ãä¾å¤ãªãã¸ã§ã¯ãããã³ãã¼åæåãããã
int main()
{
try
{
throw 123 ; // ä¾å¤ãªãã¸ã§ã¯ã®åã¯intãå¤ã¯123
}
catch ( int e )
{
// eã®åã¯intãå¤ã¯123
}
}
ä¾å¤å®£è¨ããä¾å¤ã®åã®ã¿ã§ååãæå®ãã¦ããªãå ´åãä¾å¤ã®åã®ä¸æãªãã¸ã§ã¯ããçæãããä¾å¤ãªãã¸ã§ã¯ãããã³ãã¼åæåãããã
int main()
{
try
{
throw 123 ;
}
catch ( int )
{
// intåã®ä¸æãªãã¸ã§ã¯ããçæãããä¾å¤ãªãã¸ã§ã¯ãããã³ãã¼åæåããã
// ååããªãã®ã§ãåç
§ããæ¹æ³ã¯ãªã
}
}
ä¾å¤å®£è¨ã®ååã®æã示ããªãã¸ã§ã¯ãããããã¯ç¡åã®ä¸æãªãã¸ã§ã¯ãã®å¯¿å½ã¯ãå¦çããã³ãã©ã¼ããæãã ãã¦ããã³ãã©ã¼å
ã§åæåãããä¸æãªãã¸ã§ã¯ãã解æ¾ãããå¾ã§ããã
struct S
{
int * p ;
S( int * p ) : p(p) { }
~S() { *p = 0 ; }
} ;
int main()
{
try
{
throw 123 ;
}
catch ( int e )
{
S s( &e ) ;
// sãç ´æ£ãããå¾ã«ãeãç ´æ£ããã
}
}
ãã®ãããä¸ã®ã³ã¼ãã¯åé¡ãªãåä½ããããªããªãã°ãeãç ´æ£ãããã®ã¯sãããå¾ã ããã ã
ãã³ãã©ã¼ã®ä¾å¤å®£è¨ããéconstãªåã®ãªãã¸ã§ã¯ãã®å ´åããã³ãã©ã¼å
ã§ãã®ãªãã¸ã§ã¯ãã«å¯¾ããå¤æ´ã¯ãthrowå¼ã«ãã£ã¦çæãããä¸æçãªä¾å¤ãªãã¸ã§ã¯ãã«ã¯å½±é¿ããªãã
int main()
{
try
{
try
{
throw 0 ;
}
catch ( int e )
{
++e ; // å¤æ´
throw ; // ä¾å¤ãªãã¸ã§ã¯ãã®åthrow
}
}
catch ( int e )
{
// eã¯0
}
}
ãã³ãã©ã¼ã®ä¾å¤å®£è¨ããéconstãªåã¸ã®ãªãã¡ã¬ã³ã¹åã®ãªãã¸ã§ã¯ãã®å ´åããã³ãã©ã¼å
ã§ãã®ãªãã¸ã§ã¯ãã«å¯¾ããå¤æ´ã¯ãthrowå¼ã«ãã£ã¦çæãããä¸æçãªä¾å¤ãªãã¸ã§ã¯ããå¤æ´ããããã®å¯ä½ç¨ã¯ããã³ãã©ã¼å
ã§åthrowãããã¨ãã«ãå¹æãæã¤ã
int main()
{
try
{
try
{
throw 0 ;
}
catch ( int & e )
{
++e ; // å¤æ´
throw ; // ä¾å¤ãªãã¸ã§ã¯ãã®åthrow
}
}
catch ( int e )
{
// eã¯1
}
}
ä¾å¤æå®(Exception specification)ã¨ã¯ãé¢æ°å®£è¨ã§ãé¢æ°ãä¾å¤ãæãããã©ãããæå®ããæ©è½ã§ããã
é¢æ°å®£è¨ã«ãããä¾å¤æå®ã®ææ³ã¯ããªãã¡ã¬ã³ã¹ä¿®é£¾åã®å¾ãã¢ããªãã¥ã¼ãã®åã«è¨è¿°ããã
T D( ä»®å¼æ°å®£è¨ ) cv修飾å ãªãã¡ã¬ã³ã¹ä¿®é£¾å ä¾å¤æå® ã¢ããªãã¥ã¼ãæå®å
ä¾å¤æå®:
noexcept( å®æ°å¼ )
noexcept
void f() noexcept ;
struct S
{
void f() const & noexcept [[ ]] ;
} ;
ä¾å¤æå®ã¯ãé¢æ°å®£è¨ã¨å®ç¾©ã®ãã¡ãé¢æ°åãé¢æ°ã¸ã®ãã¤ã³ã¿ã¼åãé¢æ°åã¸ã®ãªãã¡ã¬ã³ã¹ãã¡ã³ãã¼é¢æ°ã¸ã®ãã¤ã³ã¿ã¼åã«é©ç¨ã§ãããã¾ããé¢æ°ã¸ã®ãã¤ã³ã¿ã¼åãä»®å¼æ°ãæ»ãå¤ã®åã«ä½¿ãããå ´åãæå®ã§ããã
void f() noexcept ; // OK
void (*fp)() noexcept = &f ; // OK
void (&fr)() noexcept = f ; // OK
// OKãä»®å¼æ°ã¨ãã¦
void g( void (*fp)() noexcept ) ;
// OKãæ»ãå¤ã®åã¨ãã¦
auto h() -> void (*)() noexcept ;
struct S
{
void f() noexcept ; // OK
} ;
typedef宣è¨ã¨ã¨ã¤ãªã¢ã¹å®£è¨ã«ã¯ä½¿ç¨ã§ããªãã
typedef void (*func_ptr_type)() noexcept ; // ã¨ã©ã¼
using type = void (*)() noexcept ; // ã¨ã©ã¼
ä¾å¤æå®ã®ãªãé¢æ°å®£è¨ã¯ãä¾å¤ã許å¯ããé¢æ°ã§ããã
ä¾å¤æå®ã«noexceptãæå®ãããå ´åããã®é¢æ°ã¯ä¾å¤ã許å¯ããªãã¨æå®ãããã¨ã«ãªãã
ä¾å¤æå®ã«ãnoexcept(å®æ°å¼)ãæå®ããå®æ°å¼ãtrueã¨è©ä¾¡ãããå ´åããã®é¢æ°ã¯ä¾å¤ã許å¯ããªãã¨æå®ãããã¨ã«ãªããå®æ°å¼ãfalseã¨è©ä¾¡ãããå ´åããã®é¢æ°ã¯ä¾å¤ã許å¯ããé¢æ°ã¨æå®ãããã¨ã«ãªãã
void f1() ; // ä¾å¤ã許å¯
void f2() noexcept ; // ä¾å¤ã許å¯ããªã
void f3() noexcept( true ) ; // ä¾å¤ã許å¯ããªã
void f4() noexcept( false ) ; // ä¾å¤ã許å¯
noexcept(å®æ°å¼)ã¯ãã³ã³ãã¤ã«æã®æ¡ä»¶ã«å¾ã£ã¦ãé¢æ°ã®ä¾å¤æå®ãå¤ãããã¨ã«ä½¿ããã
template < typename T >
constexpr bool is_nothrow()
{
return std::is_fundamental<T>::value ;
}
// ãã³ãã¬ã¼ãä»®å¼æ°ãåºæ¬åãªãä¾å¤ãæããªãå®è£
ãã§ããé¢æ°
template < typename T >
void f( T x ) noexcept( is_nothrow<T>() ) ;
ãã®ä¾ã§ã¯ãé¢æ°fã¯ããã³ãã¬ã¼ãä»®å¼æ°ãåºæ¬åã®å ´åãä¾å¤ãæããªãå®è£
ãã§ãããã®ã¨ãããããã§ããã³ãã¬ã¼ãã®ã¤ã³ã¹ã¿ã³ã¹åã®éã«ãåã調ã¹ããã¨ã«ãã£ã¦ãä¾å¤ã許å¯ãããã©ãããã³ã³ãã¤ã«æã«åãæ¿ãããã¨ãã§ããã
ãããä¾å¤ã許å¯ããªãé¢æ°ããä¾å¤ã®throwã«ãã£ã¦æãåºããå ´åãstd::terminateãå¼ã°ããã
// ä¾å¤ã許å¯ããé¢æ°
void allow_exception()
{
throw 0 ; // OK
}
// ä¾å¤ã許å¯ããªãé¢æ°
void disallow_exception() noexcept
{
try
{
throw 0 ; // OKãä¾å¤ã¯é¢æ°ã®å¤ã«æããªã
}
catch ( int ) { }
throw 0 ; // å®è¡æã«std::terminateãå¼ã°ãã
}
ä¾å¤ã許å¯ããªãã¨ããã®ã¯ãä¾å¤ã«ãã£ã¦é¢æ°ããæãåºããã¨ãç¦æ¢ãããã®ã§ãããé¢æ°ã®ä¸ã§ä¾å¤ã使ããã¨ãç¦æ¢ãããã®ã§ã¯ãªãã
ä¾å¤ã許å¯ããªãé¢æ°ã¯ãä¾å¤ãæããå¯è½æ§ããã£ãã¨ãã¦ããéæ³ã§ã¯ãªããC++å®è£
ã¯ããã®ãããªã³ã¼ããåæ³ã«ããããã«æ確ã«ç¾©åä»ãããã¦ããã
void f() noexcept
{
throw 0 ; // OKãã³ã³ãã¤ã«ãéã
// å®è¡æã«std::terminateãå¼ã°ãã
}
void g( bool b ) noexcept
{
if ( b )
throw 0 ; // OKãã³ã³ãã¤ã«ãéã
// å®è¡æã«bãtrueã®å ´åãstd::terminateãå¼ã°ãã
}
ãã¡ããããã®ãããªé¢æ°ãå¼ã³åºãã¦ãçµæã¨ãã¦é¢æ°ã®å¤ã«ä¾å¤ãæããããå ´åãstd::terminateãå¼ã°ããã
ãã®ä»ã«ãC++11ã§ã¯éæ¨å¥¨(deprecated)æ±ãã«ãªã£ã¦ããæ©è½ã«ãåçä¾å¤æå®(dynamic-exception-specification)ãããããã®æ©è½ã¯å°æ¥å»æ¢ãããã®ã§ã詳ãã解説ããªãããæ¦ã以ä¸ã®ãããªæ©è½ã¨ãªã£ã¦ããã
// ä¾å¤ã許å¯ããªã
void f() throw( ) ;
// intåã®throwã許å¯ãã
void g() throw( int ) ;
// intåã¨shortåã®throwã許å¯ãã
void h() throw( int, short ) ;
åçä¾å¤æå®ã®ããé¢æ°ã§ã¯ãä¾å¤ãé¢æ°ã®å¤ã«throwããã¨ãstd::unexpectedãå¼ã°ãããããã許å¯ããåã®ä¾å¤ãthrowããå ´åã¯ããã®ã¾ã¾ãã³ãã©ã¼ã®æ¤ç´¢ãè¡ããããã許å¯ããªãåãthrowããå ´åã¯ãstd::terminateãå¼ã°ããã¨ããã¦ããã
å°ãªãã¨ããå½åã®C++ã®è¨è¨ã¯ããã§ãã£ãããç¾å®ã«ã¯ããã®ããã«å®è£
ããC++å®è£
ã¯åºã¦ããªãã£ããã»ã¨ãã©ã®å®è£
ã§ã¯ãåçä¾å¤æå®ã¯ãåã«ç¡è¦ãããã
ãã®å¾ãä½ãä¾å¤ã¨ãã¦è¨±å¯ããåãæå®ããªããthrow()ã ãããæ¬æ¥ã®è¨è¨ã¨ã¯éãæå³ã§ä½¿ããã ãããé¢æ°ãå¤ã«ä¾å¤ãæããªãä¿è¨¼ãè¨è¿°ããããã«ä½¿ããã ããã®ã ããã®ãä¾å¤ãé¢æ°ã®å¤ã«æããªãä¿è¨¼ã¨ããã®ã¯ãã¨ã¦ã便å©ã ã£ãã®ã§ãC++11ã§ã¯å°ç¨ã®ææ³ãä¸ããããç¡ä¾å¤æå®ã¨ãã¦è¿½å ããããããã¦ãåçä¾å¤æå®ã¯ãç¾å®ã«å®è£
ããã¦ããªããã¨ãããéæ¨å¥¨ã«å¤æ´ããããå°æ¥çã«ã¯åãé¤ãããäºå®ã ã
ã¯ã©ã¹ã®æé»ã«å®£è¨ãããç¹å¥ãªã¡ã³ãã¼é¢æ°ã¯ããã®åçä¾å¤æå®ãæé»ã«æå®ãããããã®åãªã¹ãã¯ãæé»ã®å®è£
ãå¼ã³åºãé¢æ°ãæããå¯è½æ§ã®ããä¾å¤ã®ã¿ãæã¤ã
ããã¯ãåºæ¬ã¯ã©ã¹ãéstaticã¡ã³ãã¼ããæ示çã«ä¾å¤ã許å¯ãããã®ã§ãªãããããã¯ã©ã¹ã®æé»ã®ç¹å¥ãªã¡ã³ãã¼ã¯ãç¡ä¾å¤æå®ãããã¨ãããã¨ã§ããã
class S
{
// æé»ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ããã¹ãã©ã¯ã¿ã¼ã代å
¥æ¼ç®åã¯ã
// ä¾å¤æå®throw()ãæå®ããã
} ;
解æ¾é¢æ°ã®å®£è¨ã«ãæ示çãªä¾å¤æå®ããªãå ´åã¯ãnoexcept(true)ãæå®ããããã®ã¨ã¿ãªãããã
// æé»ã«noexcept(true)ãæå®ããã
void operator delete( void * ) ;