使用隐式转换到char数组或编写显式转换方法是明智的吗?

时间:2015-05-26 16:57:23

标签: c++ string operator-overloading implicit-conversion

我正在为UTF-8字符串编写一个字符串类,我遇到了设计问题。

我希望我的一些方法同时将const char *const Utf8String &作为输入值。这是为了避免在用户通过Utf8String时计算长度并验证UTF-8字符串,并避免在用户通过{{1}时为临时Utf8String分配无用的内存}}

我还想重载const char *运算符(相当于const char *)因为它很方便。问题在于它会产生一种模糊性。

这就是STL字符串提供string::c_str()方法而不是重载运算符c_str()的原因吗?

我能在这做什么?保留重载的运算符const char *,并且只有我的方法的两个可能签名之一(const char *const char *),或删除const Utf8String &运算符重载并保持两者可能方法签名?

2 个答案:

答案 0 :(得分:1)

我建议编写两种方法,而不是使用(const char*)运算符。它可能会导致各种问题。

问题是,如何管理返回指针的内存?

可以编写这样的致命代码:

const char* getText() {
    YourType x = "text";
    return x;
}

在这里,您的类型被破坏,并且很可能也是您的char数组。但这个编译很好,看起来也很好。很难发现代码中的问题。

使用专用方法可以让您明确使用:

class YourType {
public:
    const char* createCharArray() const;
    const char* accessCharArray() const;
}

一个方法将分配一个新的char数组,而另一个方法将只创建一个内部临时char表示,该表示将使用该类型本身销毁。

另一个问题是使用这样的构造函数:

class YourType {
public:
    YourType(const char *str);
}

实际上并不清楚这个构造函数的作用。您的类是否存储指向字符串的指针,或者您的类是否创建了字符串的内部副本。这很可能导致代码难以理解。

void printText(const YourType &text) {
}

允许这样:

printText("Text");

但也适用于此:

void foo(const char* text) {
    char *str = new char[strlen(text)+1];
    std::strcpy(str, text);
    printText(str);
}

我建议您使用static转换方法:

class YourType {
public:
    static YourType fromCharArray(const char *str);
}

答案 1 :(得分:0)

编写自己的字符串类非常有趣(并且是一个很好的练习)。但我发现标准std::string非常适用于UTF-8字符串。

在我完全偏离主题之前,我对你的问题的回答是:当有疑问时,模仿标准事物(即std::string)。至少有两个原因可以解决这个问题。 首先,这些接口通常设计得很好(因为许多具有不同背景的人正在研究它们)。 第二,开发人员通常已经知道如何正确使用这些东西。

但回到UTF-8字符串。我不知道为什么你需要一个单独的类来表示UTF-8字符串以及你花了多少时间思考你是否真的需要它(我很好奇你知道原因)。问题是UTF-8是Unicode标准的一部分,并不那么简单。如果你想要一个功能齐全的UTF-8字符串,你最终会实现unicode标准的一个不错的部分(比如规范化形式,奇怪的大写规则(你知道吗,希腊语字母Sigma有不同的大小写规则)在这个词的末尾?),等等。我确定你不想这样做,因为如果你需要它,最好使用ICU,Qt或其他一些具有良好Unicode支持的库。

所以,如果你需要的只是一个Utf-8字符的存储,其中有一些utf8_to_encoding()utf8_from_encoding()utf8_next_code_point()我建议坚持std::string并提供其他作为免费功能所需的功能。例如:

std::string utf8_from_utf16(const uint16_t *s, size_t len);

也许关于类似主题的我another answer也可能有用。