C++での暗黙的な変換

3249 ワード

まず、クラス構造関数の暗黙的な変換という比較的一般的な技術を見てみましょう.ここでは先に説明しますが、その後の例では、できるだけ主な内容を強調するために、十分な条件として必要ではない条件であるものを無視するので、設計されたコードの中には「不完全」の疑いがあります.すべての脆弱性を塞ぐために、コード全体が私が紹介したい技術ではなく、「苦行僧」式のプログラミングの原則に重点を置いているように感じられることが多いからです.
C++は次の関数のような厳格な言語であることを知っています.
 
  • void test_int_proxy(const int_proxy& v) {
  • printf("%d", v.value());
  • }

  • 呼び出し者はその伝参もint_であるべきだ.Proxyのオブジェクトですが、実際の状況はそうではありません.では、どのように表現すればいいのか、個人的には、コンパイラがそのパスをint_であるべきだと思います.proxyオブジェクト.この2つの表現の違いは、「呼び出し者」と「コンパイラ」の違いです.実際の例を見てみましょうintを仮定しますProxyクラスは次のように定義されています.
     
  • class int_proxy {
  • public:
  • int_proxy(int n) : _m(n) {};
  • public:
  • int value() const {
  • return _m;
  • }
  • private:
  • int _m;
  • };

  • このクラスは非常に簡単で、パラメータ付きの構造関数があり、パラメータリスト形式でクラスのメンバー変数を初期化します.
    一般的にtestを呼び出すint_proxyメソッド:
        test_int_proxy(int_proxy(100));

    この書き方に異論はないと思いますが、次のような書き方が出てくると納得できないかもしれません.
        test_int_proxy(100);

    しかし、この書き方は上記のクラスの定義にとって合法的です!その効果とint_の使用proxy制御は同じです.これはなぜですか.これがクラス構造関数の暗黙的な変換技術である.C++コンパイラはtest_int_Proxyメソッドはconstタイプのint_を伝達するはずですProxyオブジェクトですが、パラメータがオブジェクトではないことが分かった場合、クラスでこのパラメータを使用してオブジェクトを構築できる方法で一時的なオブジェクトを構築します.我々の例では、参照100はint型データであり、int_Proxyにはintパラメータを持つ構造関数がちょうどあります.クラス構造関数の暗黙的な変換に必要な条件を少しまとめます.
  • パラメータタイプに厳密に対応する関数が見つからない
  • は、パラメータタイプが厳密に一致するクラスの構造関数
  • を見つける.
  • 暗黙変換は一時的なオブジェクトを構成するので変更できないため、暗黙変換をトリガする関数のパラメータタイプはconst修飾
  • を使用する必要がある.
    しかし、個人的にはこのような「奇抜な淫技」は使わないほうがいいと思います.たとえば、コードには次の関数があります.
     
  • void test_int_proxy(const int& v) {
  • printf("%d", v + 100);
  • }

  • では、C++コンパイラは、パス100の呼び出しに対して上記の手順を実行します.このような関数呼び出しには2つの一致する呼び出し方法があり、不確実性が発生します.ここでは、コンパイラがどの方法を呼び出すかの不確実性ではなく、このコードを維持している人が上記のコードを調整するときに、いくつかの問題を無視しやすいことによる「人災」を指します.
    たとえば、コードに次のクラスとメソッドを追加します.
     
  • class int_proxy_2 {
  • public:
  • int_proxy_2(int n) : _m(n) {};
  • public:
  • int value() const {
  • return _m + 100;
  • }
  • private:
  • int _m;
  • };
  •  
  • void test_int_proxy(const int_proxy_2& v) {
  • printf("%d", v.value());
  • }

  • では、コンパイラは暗黙的な変換がどのクラスを変換するのか、どのtestを呼び出すのか分からない.int_proxyメソッドです.
    クラスコンストラクタの暗黙的な変換を制限する方法も簡単です.対応するコンストラクタにexplictキーワードを付けることです.
     
  • class int_proxy {
  • public:
  • explicit int_proxy(int n) : _m(n) {};

  • このように暗黙的な変換によって一時的なオブジェクトを構築する計画は、察知され、禁止される.