【问题标题】:Return a "const char*" as std::string& from a class method从类方法返回一个“const char*”作为 std::string&
【发布时间】:2018-06-14 07:56:43
【问题描述】:

我有一个返回 C-String 的 C-Libraray 函数

const char* myFuncC(struct myS *);

现在我写一个类映射器:

class myC {
  private:
    struct myS * hdl
    ...
  public:
    const char* myFunc() {
      return myFuncC(hdl);
    }

  // want to have...
    const std::string& myFuncS() {
      return ??? myFuncC(hdl);
    }
}

现在我想返回一个:const std::string& 而我不想想要复制 C-String 指针数据

我该怎么做?

更新

是否有像 const C++-String 类并使用 const C-String 指针 作为字符串源的 C++ 类?

我会称这个类为 C++-String-External ... External 意思是...使用 external 源作为存储...在我的例子中是"常量字符 *"

【问题讨论】:

  • 我更新了这个例子……对,我想让 const std:.string& 作为类方法的返回。
  • 你在猜。不。获取good C++ book
  • 没有魔法可以让你返回一个没有引用的底层对象的引用。而且,如果您希望避免悬空引用地狱,请不要使用引用进行货物崇拜编程。首选值而不是引用作为默认值。
  • 因为您的请求的本质表明对某些 C++ 基础知识存在误解。这并不是指出您个人的缺点,而是帮助您总体上编写更好的 C++,并避免将来出现此类问题。
  • @AndreasOtto 请不要那么固执。 std::string 是一个类,它具有各种额外的特性。该字符串在内部存储一个以空字符结尾的字符数组(从 C++11 开始)。但那里还有更多。您不能简单地将 C 风格的字符数组解释为 C++ std::string

标签: c++ string reference


【解决方案1】:

std::string,根据定义,拥有它的内存,我们无法改变它。此外,通过返回 reference,您正在创建对局部变量的悬空引用(或内存泄漏)。

然而,在类似字符串的接口中封装连续字符范围而不进行复制的想法是如此普遍,以至于 C++17 添加了一个新类型 std::string_view 来实现这一点。有了它,你的代码可以写成:

std::string_view myFuncS() {
    return {myFuncC(hdl)};
}

string_view 不是字符串,但它有一个非常相似的 API,其想法是使用它来代替 string const& 的许多当前用途。非常适合这里的工作。

请注意,我们返回副本,以避免悬空引用。但是,这不会复制底层内存,而且成本很低——几乎和返回引用一样便宜。

【讨论】:

    【解决方案2】:

    只需返回一个新字符串:

    std::string myFuncS() {
      return std::string(myFuncC(hdl));
    }
    

    如果你真的需要引用或指针,那么在堆上分配字符串并返回一个指向它的指针:

    std::unique_ptr<std::string> myFuncS() {
           return std::unique_ptr<std::string>(new std::string(myFuncC(hdl)));
    }
    

    【讨论】:

    • 1.我有一个底层 C-API 函数,C-String 是我的 FIXED 限制。 2. 在您的示例中,您仍然将 C-String 复制到堆中。我根本不想复制 C-String 数据。
    • @AndreasOtto 您需要将const char* 复制到string 中。看看string_view这是你需要的(需要C++ 17)stackoverflow.com/questions/20803826/what-is-string-view
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-10
    • 1970-01-01
    • 2021-02-24
    • 1970-01-01
    • 2011-01-07
    • 1970-01-01
    • 2010-10-22
    相关资源
    最近更新 更多