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