質問

I'm writing a String class. I'd like to be able to assign my strings such as;

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

I've already assigned my operator=() method for string to integer conversion. How can I declare another operator=() so that I can do the reverse method?

When I declare another, it seems to override the previous.

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);
//}
役に立ちましたか?

解決

A single-argument constructor can act as an int->String conversion, whereas a so-called conversion operator does the converse 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
};

Note however, that these conversions will happen implicitly and you can easily get bitten. Suppose you would extend this class to also accept std::string arguments and conversions

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
};

and you would have these two function overloads

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

Now try and call fun(String()). You get a compile error because there are multiple -equally viable- implicit conversions. THat's why C++98 allows the keyword explicit in front of single-argument constructors, and C++11 extends that to explicit conversion operators.

So you would write:

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

One example where implicit conversion might be legitate is for smart pointer classes that want to convert to bool or (if they are templated) from smart_pointer<Derived> to smart_pointer<Base>.

他のヒント

Rather than assignment operators, you probably want conversion operators—there's no way you can define an additional assignment operator for int. In your String class, you might write:

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

You can add assignment operators in addition to the first, but they generally aren't necessary except for optimization reasons.

And finally, I think you'll find this a bad idea. It's good if the goal is obfuscation, but otherwise, implicit conversions tend to make the code less readable, and should be avoided except in obvious cases (e.g. a Complex class should have a converting constructor from double). Also, too many implicit conversions will result in ambiguities in overload resolution.

To convert your class to the other you need conversion operator. Something like this:

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
    {

    }
};

To enable int n = a (where a is an object of your string class) you need a conversion operator.

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

To enable conversion to your type, you need a converting assignment and possibly a conversion constructor.

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

You will also need overloads for const char*, char* and so on.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top