3

我正在写一个字符串类。我希望能够分配我的字符串,例如;

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

你会有这两个函数重载

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或(如果它们是模板化的)从smart_pointer<Derived>to smart_pointer<Base>

于 2012-08-09T12:38:28.387 回答
4

您可能需要转换运算符而不是赋值运算符 - 您无法为int. 在你的String课堂上,你可能会写:

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

除了第一个之外,您还可以添加赋值运算符,但它们通常不是必需的,除非出于优化原因。

最后,我想你会发现这是个坏主意。如果目标是混淆,那很好,但除此之外,隐式转换往往会降低代码的可读性,并且应该避免,除非在明显的情况下(例如,一个Complex类应该有一个转换构造函数 from 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 回答