通过重写 Java 的 String.toUpperCase() 返回空字符数组 [重复]

Posted

技术标签:

【中文标题】通过重写 Java 的 String.toUpperCase() 返回空字符数组 [重复]【英文标题】:Returning null char array with rewriting Java's String.toUpperCase() [duplicate] 【发布时间】:2014-03-18 13:29:47 【问题描述】:

我最初是一名 Java 程序员,我非常喜欢语法,尤其是关于 String 对象。使用 C++,我尝试重新创建 Java 拥有的 toUpperCase() 方法。唯一的问题是它总是返回一个 String 具有空/NULL char 数组的对象。

String String::toUpperCase()

    char *a = new char[this->length + 1];
    memset(a, 0, this->capacity + 1);
    memcpy(a, this->characters, this->length);
    for (int i = 0; i < strlen(this->characters); i++)
    
        toupper(a[i]);
    
    return *new String(a);

【问题讨论】:

一般来说,使用这里的东西会更明智:***.com/questions/735204/… 和 std::string。每次调用此函数时都会泄漏内存。另外,请阅读toupper 的一些文档。 对字符串使用 std::string 另外:在 Java 和 C# 中,您经常使用 new,在 C++ 中,您应该尽可能避免使用它(无 GC)。 作为一般规则,不要尝试在 C++ 类中重新创建 java 类 API(它们针对 Java 进行了优化,所以你最终得到的往往是“我可以编写 C 代码”的变体任何语言”主题)。要将 C++ 字符串转换为大写,请参阅this answer。 另一方面,停止滥用指针(即你应该写return String(a);而不是'return *new String(a);'并在a上使用智能指针,或者更好的是,a std::vector);另外,停止写this-&gt;。这是不必要的。还可以考虑使用std::fill 代替memsetstd::copy 代替memcpy 【参考方案1】:

您的尝试存在一些记忆问题,以及逻辑问题。您只需要返回一个字符为大写的字符串副本:

std::string str = "My Original string";
std::string myCopy(str);
std::locale loc;
std::transform(myCopy.begin(), myCopy.end(), myCopy.begin(), [&](char c)

    return std::toupper(c, loc);
);

【讨论】:

如果您不需要区域设置敏感度,则只需 std::transform(myCopy.begin(), myCopy.end(), myCopy.begin(), std::toupper) @japreiss,这并不总是那么好,尽管如果char 被签名并且有负值,答案也不会。您可以查看我评论的链接以获取有关此方法的更多讨论。 @japreiss 我认为,在对文本进行操作时,不使用语言环境总是会被破坏——如何排除使用语言环境的需要?话又说回来,C++ 中的语言环境无论如何都被破坏了(即上面对德语文本“Maß”做了错误的事情,无论语言环境如何)。 @japreiss 使用不带语言环境的版本的主要问题是它是 C 标准库的继承,它采用并返回具有非常具体标准的 int .如果char 在给定平台上签名,则对int std::toupper(int) 的调用可能会导致未定义的行为。 谢谢,我猜我的错误评论变成了一个很好的学习经验:)

以上是关于通过重写 Java 的 String.toUpperCase() 返回空字符数组 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

java中怎样避免方法被重写

重载和重写有啥区别

Java Set集合通过重写hashCode和equals实现去重

Java重载和重写

深入理解Java中的重写和重载

java-方法重写的注意事项