3

私はStringクラスを書いています。次のような文字列を割り当てられるようにしたいと思います。

a = "foo";
printf(a);
a = "123";
printf(a);
int n = a; // notice str -> int conversion
a = 456; // notice int -> str conversion
printf(a);

文字列から整数への変換には、operator =()メソッドをすでに割り当てています。逆のメソッドを実行できるように、別のoperator =()を宣言するにはどうすればよいですか?

私が別のものを宣言するとき、それは前のものを上書きするようです。

String::operator const char *() {
    return cpStringBuffer;
}
String::operator const int() {
    return atoi(cpStringBuffer);
}
void String::operator=(const char* s) {
    ResizeBuffer(strlen(s));
    strcpy(cpStringBuffer, s);
}
bool String::operator==(const char* s) {
    return (strcmp(cpStringBuffer, s) != 0);
}

//void String::operator=(int n) {
//  char _cBuffer[33];
//  char* s = itoa(n, _cBuffer, 10);
//  ResizeBuffer(strlen(_cBuffer));
//  strcpy(cpStringBuffer, _cBuffer);
//}
4

4 に答える 4

5

単一引数のコンストラクターはint->String変換として機能できますが、いわゆる変換演算子はその逆のint->Stringを実行します

class String
{
public:
    String(int)            {} // initialization of String with int
    String& operator=(int) {} // assignment of int to String

    operator int() const {} // String to int
};

ただし、これらの変換は暗黙的に行われ、簡単に噛まれる可能性があることに注意してください。このクラスを拡張して、std::string引数と変換も受け入れるとします。

class String
{
public:
    String(int)          {} // int to String
    String(std::string)  {} // std::string to String

    // plus two assignment operators 

    operator int() const       {} // String to int
    operator std::string const {} // String to std::string
};

そして、これらの2つの関数のオーバーロードが発生します

void fun(int)         { // bla }
void fun(std::string) { // bla }

次に、を呼び出してみてくださいfun(String())。複数の-等しく実行可能な-暗黙の変換があるため、コンパイルエラーが発生します。これが、C ++ 98がexplicit単一引数コンストラクターの前でキーワードを許可し、C++11がそれをexplicit変換演算子に拡張する理由です。

だからあなたは書くでしょう:

class String
{
public:
    explicit String(int)          {} // int to String
    explicit operator int() const {} // String to int 
};

bool暗黙の変換が正当である可能性がある1つの例は、に、または(テンプレート化されている場合は)からsmart_pointer<Derived>に変換するスマートポインタークラスの場合smart_pointer<Base>です。

于 2012-08-09T12:38:28.387 に答える
4

代入演算子ではなく、おそらく変換演算子が必要です。 に対して追加の代入演算子を定義する方法はありませんintStringクラスでは、次のように記述できます。

class String
{
    //  ...
public:
    String( int i );           //  Converting constructor: int->String
    operator int() const;      //  conversion operator: String->int
    //  ...
};

最初のものに加えて代入演算子を追加できますが、最適化の理由を除いて、通常は必要ありません。

そして最後に、これは悪い考えだと思うでしょう。目的が難読化であれば良いのですが、それ以外の場合、暗黙的な変換はコードを読みにくくする傾向があるため、明らかな場合を除いて避ける必要があります (たとえば、Complexクラスには からの変換コンストラクターが必要doubleです)。また、暗黙的な変換が多すぎると、オーバーロードの解決があいまいになります。

于 2012-08-09T12:42:36.693 に答える
2

クラスを他のクラスに変換するには、が必要conversion operatorです。このようなもの:

struct Foo
{
    operator int() const //Foo to int 
    {
        return 10;
    }

    operator=(int val) //assign int to Foo
    {

    }

    operator=(const std::string &s) //assign std::string to Foo
    {

    }
};
于 2012-08-09T12:37:52.590 に答える
1

有効にするにint n = aは(aは文字列クラスのオブジェクトです)、変換演算子が必要です。

class string {
  public:
    operator int() const { return 23; }
};

タイプへの変換を有効にするには、変換割り当てと、場合によっては変換コンストラクターが必要です。

class string {
  public:
    string(int i);
    string& operator=(int i);
};

const char*、などのオーバーロードも必要char*になります。

于 2012-08-09T12:38:34.367 に答える