C ++の明示的なキーワード

C ++のexplicitキーワードは、1つのパラメーターのみでクラスコンストラクターを変更するために使用されます。その機能は、コンストラクターが暗黙的ではなく明示的であることを示すことです。それに対応する別のキーワードは暗黙的であり、非表示を意味します。
クラスコンストラクタは、デフォルトで暗黙的に宣言されています。
最後の例:

class CxString  // 没有使用explicit关键字的类声明, 即默认为隐式声明  
{
    
      
public:  
    char *_pstr;  
    int _size;  
    
    CxString(int size)  
    {
    
      
        _size = size;                // string的预设大小  
        _pstr = malloc(size + 1);    // 分配string的内存  
        memset(_pstr, 0, size + 1);  
    }  
    
    CxString(const char *p)  
    {
    
      
        int size = strlen(p);  
        _pstr = malloc(size + 1);    // 分配string的内存  
        strcpy(_pstr, p);            // 复制字符串  
        _size = strlen(_pstr);  
    }  
    // 析构函数这里不讨论, 省略...  
};  
  
    // 下面是调用:  
  
    CxString string1(24);     // 这样是OK的, 为CxString预分配24字节的大小的内存  
    CxString string2 = 10;    // 这样是OK的, 为CxString预分配10字节的大小的内存  
    CxString string3;         // 这样是不行的, 因为没有默认构造函数, 错误为: “CxString”: 没有合适的默认构造函数可用  
    CxString string4("aaaa"); // 这样是OK的  
    CxString string5 = "bbb"; // 这样也是OK的, 调用的是CxString(const char *p)  
    CxString string6 = 'c';   // 这样也是OK的, 其实调用的是CxString(int size), 且size等于'c'的ascii码  
    string1 = 2;              // 这样也是OK的, 为CxString预分配2字节的大小的内存  
    string2 = 3;              // 这样也是OK的, 为CxString预分配3字节的大小的内存  
    string3 = string1;        // 这样也是OK的, 至少编译是没问题的, 但是如果析构函数里用free释放_pstr内存指针的时候可能会报错, 完整的代码必须重载运算符"=", 并在其中处理内存释放

上記のコードで、「CxString string2 = 10;」という文がOKなのはなぜですか?C ++では、コンストラクターにパラメーターが1つしかない場合、コンパイル時にデフォルトの変換操作が行われます。コンストラクターのデータ型に対応するデータつまり、 "CxString string2 = 10;"このコードでは、コンパイラは整数型をCxStringオブジェクトに自動的に変換します。これは、実際には次の操作と同等です。

CxString string2(10);  
或  
CxString temp(10);  
CxString string2 = temp;  

ただし、上記のコードの_sizeは文字列メモリ割り当てのサイズを表すため、呼び出しの2番目の文「CxStringstring2 = 10;」と6番目の文「CxStringstring6 = 'c';」は説明がなく、簡単です。戸惑う。
この使用を防ぐ方法はありますか?答えは、明示的なキーワードを使用することです。上記のコードを次のように変更してみましょう。

class CxString  // 使用关键字explicit的类声明, 显示转换  
{
    
      
public:  
    char *_pstr;  
    int _size;  
    explicit CxString(int size)  
    {
    
      
        _size = size;  
        // 代码同上, 省略...  
    }  
    CxString(const char *p)  
    {
    
      
        // 代码同上, 省略...  
    }  
};  
  
    // 下面是调用:  
  
    CxString string1(24);     // 这样是OK的  
    CxString string2 = 10;    // 这样是不行的, 因为explicit关键字取消了隐式转换  
    CxString string3;         // 这样是不行的, 因为没有默认构造函数  
    CxString string4("aaaa"); // 这样是OK的  
    CxString string5 = "bbb"; // 这样也是OK的, 调用的是CxString(const char *p)  
    CxString string6 = 'c';   // 这样是不行的, 其实调用的是CxString(int size), 且size等于'c'的ascii码, 但explicit关键字取消了隐式转换  
    string1 = 2;              // 这样也是不行的, 因为取消了隐式转换  
    string2 = 3;              // 这样也是不行的, 因为取消了隐式转换  
    string3 = string1;        // 这样也是不行的, 因为取消了隐式转换, 除非类实现操作符"="的重载

明示的なキーワードの役割は、クラスコンストラクターの暗黙的な自動変換を防ぐことです。

前述のように、明示的キーワードは、パラメーターが1つのクラスコンストラクターに対してのみ有効です。クラスコンストラクターパラメーターが2以上の場合、暗黙的な変換は行われないため、明示的キーワードは無効です。例えば:

class CxString  // explicit关键字在类构造函数参数大于或等于两个时无效  
{
    
      
public:  
    char *_pstr;  
    int _age;  
    int _size;  
    explicit CxString(int age, int size)  
    {
    
      
        _age = age;  
        _size = size;  
        // 代码同上, 省略...  
    }  
    CxString(const char *p)  
    {
    
      
        // 代码同上, 省略...  
    }  
};  
  
    // 这个时候有没有explicit关键字都是一样的

ただし、例外があります。つまり、最初のパラメーター以外の他のパラメーターにデフォルト値がある場合、明示的なキーワードは引き続き有効です。このとき、コンストラクターが呼び出されると、1つのパラメーターのみが渡されます。これは、 1つのパラメーター。クラスコンストラクター、例は次のとおりです。

class CxString  // 使用关键字explicit声明  
{
    
      
public:  
    int _age;  
    int _size;  
    explicit CxString(int age, int size = 0)  
    {
    
      
        _age = age;  
        _size = size;  
        // 代码同上, 省略...  
    }  
    CxString(const char *p)  
    {
    
      
        // 代码同上, 省略...  
    }  
};  
  
    // 下面是调用:  
  
    CxString string1(24);     // 这样是OK的  
    CxString string2 = 10;    // 这样是不行的, 因为explicit关键字取消了隐式转换  
    CxString string3;         // 这样是不行的, 因为没有默认构造函数  
    string1 = 2;              // 这样也是不行的, 因为取消了隐式转换  
    string2 = 3;              // 这样也是不行的, 因为取消了隐式转换  
    string3 = string1;        // 这样也是不行的, 因为取消了隐式转换, 除非类实现操作符"="的重载

上記は、C ++のexplicitキーワードの詳細な紹介です。

総括する

明示的なキーワードは、クラス内の単一引数コンストラクターの前でのみ使用する必要があります。パラメータレスコンストラクタとマルチパラメータコンストラクタは常に明示的に呼び出されるため、この場合、コンストラクタの前に明示を追加しても意味がありません。

グーグルのC ++仕様で明示的に言及されている利点は、タイムリーでない型変換を回避できることであり、欠点はありません。したがって、Googleは、すべての単一パラメーターコンストラクターを表示する必要があることに同意します。まれに、コピーコンストラクターを明示的に宣言できない場合があります。たとえば、他のクラスの透過ラッパーとして機能するクラス。

効果的なc ++によると:明示的として宣言されたコンストラクターは、通常、非明示的な兄弟よりも人気があります。コンパイラが予期しない(そして多くの場合予期しない)型変換を実行することを禁止しているためです。コンストラクターを暗黙的な型変換に使用できるようにする正当な理由がない限り、コンストラクターを明示的と​​して宣言し、すべての人が同じポリシーに従うことをお勧めします。

元のリンクを提供しますhttps//www.cnblogs.com/rednodel/p/9299251.html

おすすめ

転載: blog.csdn.net/qq_24649627/article/details/111217849