Saturday, February 20, 2016

[C++] explicit

Ex:
struct A
{
    A(int) { }      // converting constructor
    A(int, int) { } // converting constructor (C++11)
    operator int() const { return 0; }
};
 
struct B
{
    explicit B(int) { }
    explicit B(int, int) { }
    explicit operator int() const { return 0; }
};
 
int main()
{
    A a1 = 1;      // OK: copy-initialization selects A::A(int)
    A a2(2);       // OK: direct-initialization selects A::A(int)
    A a3 {4, 5};   // OK: direct-list-initialization selects A::A(int, int)
    A a4 = {4, 5}; // OK: copy-list-initialization selects A::A(int, int)
    int na1 = a1;  // OK: copy-initialization selects A::operator int()
    int na2 = static_cast<int>(a1); // OK: static_cast performs direct-initialization
    A a5 = (A)1;   // OK: explicit cast performs static_cast
 
//  B b1 = 1;      // error: copy-initialization does not consider B::B(int)
    B b2(2);       // OK: direct-initialization selects B::B(int)
    B b3 {4, 5};   // OK: direct-list-initialization selects B::B(int, int)
//  B b4 = {4, 5}; // error: copy-list-initialization does not consider B::B(int,int)
//  int nb1 = b2;  // error: copy-initialization does not consider B::operator int()
    int nb2 = static_cast<int>(b2); // OK: static_cast performs direct-initialization
    B b5 = (B)1;   // OK: explicit cast performs static_cast
}
 
Specifies constructors and conversion operators  that don't allow implicit conversions or copy-initialization.


EX : 
class String{
      explicit String(int n);
      String(const char *p);
};
String s1 = 'a'; //error:不能做隐式char->String转换 implicit conversition
String s2(10);   //correct:调用explicit String(int n);
String s3 = String(10);//correct:调用explicit String(int n);再调用默认的复制构造函数 (Initialization by copy)
String s4 = "Brian"; //correct:隐式转换调用String(const char *p);再调用默认的复制构造函数
String s5("Fawlty"); //correct:正常调用String(const char *p); 
 
void f(String);
­
String g(){
    f(10); //error:不能做隐式int->String转换
    f("Arthur"); //correct:隐式转换,等价于f(String("Arthur"));
    return 10; //error:不能做隐式int->String转换 should be : return (B)10;
}


Tips :

In reality,  implicit conversions or copy-initialization would cause some problems if we don't pay attention. So it's better to forbidden these. We use explicit before constructor or operator, to tell the compiler not to do the copy-initialization or implicit conversation.

No comments:

Post a Comment