Reputation: 3352
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);
//}
Upvotes: 3
Views: 3395
Reputation: 70526
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>
.
Upvotes: 5
Reputation: 24846
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
{
}
};
Upvotes: 2
Reputation: 153919
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.
Upvotes: 4
Reputation: 59811
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.
Upvotes: 1