1

クラスがあるとします:

class foo
{
    ....
    //some constructors here set val=34
    ....
    private:
    int val;
    int & foo::operator,()
    {
      return val;
    }
};

そして、私はそれを次のように使用できるようにしたい:

foo bar;
printf("  %d ", bar);   //i need to get value of bar.val
                        //with just using bar itself with
                        //using an overloading
                        //but , overloading does not work
                        //i need to get 34 without using bar.val
                        //i need this without any getter 
                        //i need val to be private

質問: この種のオーバーロードは可能ですか? はいの場合、どのように?

私は試した:

int foo::operator int()
{
    return val;
}

しかし、「変換関数では戻り値の型が指定されていない可能性があります」と書かれています:(

私は試した:

operator int() const { return val; } 

変換は、printf & c の外でのみ機能します。

 int e=foo;
 printf(" %d ",e); //works 
4

3 に答える 3

4

クラスをオーバーロードすることはできませんが、変換演算子を使用して、そのコンテキストで予想されるパラメーターに従って自動的に異なる型に変換することができます。あなたの場合、 のようにval、次のようintに変換をオーバーロードします。int

operator int() const { return val; }

intが必要な場合に を指定するとfoo、この変換が適用されます。

いくつかの制限があります。たとえばfoo、対応する引数の型がジェネリックである関数テンプレートに渡す場合、その場所では変換は行われません。変換は、型を強制しない他の式にも影響しません。例として、fが typefooの場合、&fは常に typefoo*ではなくtype になりint*ます。ほとんどの実用的なアプリケーションでは、これらすべてがまさに必要なものです。しかし、C スタイルの可変引数printfは、明確に定義された予期される型が存在しないまさにそのようなケースだと思います。C++ スタイルの呼び出し、または明示的なキャストを使用することをお勧めしますstatic_cast<int>(f)

どちらも受け入れられない場合は、問題が発生します。文字列定数intに a が含まれているという理由だけで、C++ ロジックが hereを必要とするという事実を推測する方法はありません。%d型変換はコンパイル時に行われますが、フォーマット文字列の解釈は実行時に行われます (gcc のように警告を生成する場合を除く)。コンパイラは、その引数が必要な型がわからないため、実行する変換がわからないため、何らかの方法で彼を支援する必要があります。

これint valが の唯一のメンバーでありfoo、このクラスに仮想関数がなく、データ メンバーまたは仮想関数を持つ基底クラスが存在しない限り、クラス のオブジェクトのメモリ レイアウトはfoo通常同じです。単純な整数のそれとして。これは、型指定されていない C スタイルでprintfは、変換がまったく行われなくても、違いを見分けることができないことを意味します。しかし、これに頼るのは非常に悪いスタイルなので、これを利用しないことをお勧めします。

于 2012-09-08T21:38:14.383 に答える
2

いいえ、できません。

まず、コンマ演算子はここでは適用されません。コンマは printf 引数を区切るために使用され、演算子として使用されているコンマよりも優先されるからです。

printf の宣言が

printf(const char *,...);

つまり、コンパイラーはパラメーターがどのタイプであるべきか (最初のもの以外) を認識していないため、変換は行われません。

于 2012-09-08T21:42:30.180 に答える
2

コンマなどを過度にオーバーロードしないでください。printfには省略記号パラメーターがあるため、フィードするものは何でも受け入れます。提供するものが正しいことを確認する必要があります。複雑にしないでおく:

class foo
{
    ....
    //some constructors here set val=34
    ....
private:
    int val;
public:
    int value()
    {
      return val;
    }
};

int main()
{
    foo bar;
    printf("  %d ", bar.value());   //you get value of bar.val
}

printfバーの演算子 (変換演算子を含む) を呼び出さないため、これらは役に立ちません。持っていたとしても、次operator int()のように書く必要があります。

    printf("  %d ", (int)bar);   //you get value of bar.val

それはそれほど見栄えがよくありません。あるいは:

    printf("  %d ", +bar);   //you get value of bar.val

最も紛らわしい。

于 2012-09-08T21:33:58.470 に答える