Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 返回带有错误检查的“const std::string&”的方法_C++ - Fatal编程技术网

C++ 返回带有错误检查的“const std::string&”的方法

C++ 返回带有错误检查的“const std::string&”的方法,c++,C++,我正在编写一个函数,我想返回const std::string&。让我们看看代码 class A { public: const std::string& GetString() const { if (list.empty()) { return "Warning!"; // how to get around this line. } return list[0];

我正在编写一个函数,我想返回const std::string&。让我们看看代码

class A
{
public:
    const std::string& GetString() const
    {
        if (list.empty())
        {
            return "Warning!";    // how to get around this line.
        }
        return list[0];
    };
protected:
    std::vector<std::string> list;
};
以上代码就是一个例子。基本思想是编写一个返回常量引用的函数,但也能够检查错误

那么,如何避开返回警告


谢谢,

如果你真的想避免使用例外,那是我的第一选择,你可以考虑这个:

class A
{
public:
    const std::string& GetString() const
    {
        if (list.empty())
        {
            return warning;
        }
        return list[0];
    };
protected:
    std::vector<std::string> list;

private:
    static std::string warning;
};

// in *.cpp
std::string A::warning = "warning";

如果你真的想避免使用例外,这是我的第一选择,你可以考虑这个:

class A
{
public:
    const std::string& GetString() const
    {
        if (list.empty())
        {
            return warning;
        }
        return list[0];
    };
protected:
    std::vector<std::string> list;

private:
    static std::string warning;
};

// in *.cpp
std::string A::warning = "warning";

您可以在此函数中引发异常,并添加一个函数来检查列表是否为空。然后调用方可以在调用GetString之前进行检查。但是如果他们没有做到这一点,他们会得到一个不能忽略的异常。

您可以在此函数中抛出一个异常,并添加一个函数来检查列表是否为空。然后调用方可以在调用GetString之前进行检查。但如果他们做不到这一点,他们就会得到一个不能忽视的例外

if (list.empty()) {
    static std::string w("Warning!");
    return w;
}
因为您返回的是常量引用,所以始终返回对同一对象的引用并不重要


因为您返回的是常量引用,所以始终返回对同一对象的引用并不重要。

如果您不想使用异常,那么无论采用哪种方法都有利弊,我首先要问,要求调用方首先调用isValid方法是否合理

class A
{
public:
    bool IsStringValid() const
    {
         return !list.empty();
    }
    const std::string& GetString() const
    {
        if (list.empty())
        {
            return "";
        }
        return list[0];
    };
protected:
    std::vector<std::string> list;

private:
    static QString warning;
};

如果是我,我可能会让它返回一个const std::string*,因此NULL是一个选项,或者像Fiktik建议的那样定义一个sentinel值。

如果你不想使用异常,无论哪种方法都有利弊,我首先会问,要求调用方首先调用isValid方法是否合理

class A
{
public:
    bool IsStringValid() const
    {
         return !list.empty();
    }
    const std::string& GetString() const
    {
        if (list.empty())
        {
            return "";
        }
        return list[0];
    };
protected:
    std::vector<std::string> list;

private:
    static QString warning;
};

如果是我,我可能会让它返回一个const std::string*,因此NULL是一个选项,或者按照Fiktik的建议定义一个sentinel值。

如果您对使用字符串引用感兴趣,为什么不将字符串引用作为参数并返回布尔成功/失败标志

class A
{
public:
    const bool GetString(std::string& outString) const
    {
        if (list.empty())
            return false;

        outString = list[0];
        return true;
    };
protected:
    std::vector<std::string> list;
};
实现了相同的结果,并给出了一个简单的布尔结果


编辑:正如费鲁乔指出的那样,这不是一个可以掉以轻心的方法。以这种方式为输出使用参数容易引起混淆和错误,应谨慎使用,并在使用时做好记录。

如果您对使用字符串引用感兴趣,为什么不将字符串引用作为参数并返回布尔成功/失败标志

class A
{
public:
    const bool GetString(std::string& outString) const
    {
        if (list.empty())
            return false;

        outString = list[0];
        return true;
    };
protected:
    std::vector<std::string> list;
};
实现了相同的结果,并给出了一个简单的布尔结果


编辑:正如费鲁乔指出的那样,这不是一个可以掉以轻心的方法。以这种方式使用参数进行输出容易造成混乱和错误,应谨慎使用,并在使用的地方做好记录。

很高兴知道这一点。那么问题是什么?你可以抛出一个异常。也许我可以直接返回std::string,但还有其他想法吗?@Snowfish在正常情况下,按值返回std::string并不太昂贵-它使用隐式共享,因此真正复制的是一个轻量级包装器,而不是数据本身。所以,是的,这也是一个很好的可能性。如果您按值返回,那么现在大多数编译器都会执行一种称为返回值优化的操作。他们不会构造一个临时对象只是为了将其复制到最终位置,他们会直接构造结果,如果它应该运行的话-希望这是可以理解的。很高兴知道这一点。那么问题是什么?你可以抛出一个异常。也许我可以直接返回std::string,但还有其他想法吗?@Snowfish在正常情况下,按值返回std::string并不太昂贵-它使用隐式共享,因此真正复制的是一个轻量级包装器,而不是数据本身。所以,是的,这也是一个很好的可能性。如果您按值返回,那么现在大多数编译器都会执行一种称为返回值优化的操作。他们不会构建一个临时对象只是为了将其复制到最终位置,他们会直接构建结果——希望这是可以理解的。+1也比我的好。除了我仍然更喜欢使用错误标志,因为它们测试速度更快。我更喜欢在这种情况下使用空字符串,因为它更干净,测试速度更快,但我一直在尝试保持原始行为。另外,我不知道一个空字符串是否已经是有效的返回值。+1也比我的好。除了我仍然更喜欢使用错误标志,因为它们测试速度更快。我更喜欢在这种情况下使用空字符串,因为它更干净,测试速度更快,但我一直在尝试保持原始行为。另外,我不知道一个空字符串是否已经是一个有效的返回值。所以,通常的问题是:谁拥有一个std::string*,谁将删除它?如果你返回一个const std::string*,你几乎是在声明所有权,或者至少告诉调用方他们不负责。编译器不允许您删除cons
t指针。为什么投票被否决?那么,通常的问题是:谁拥有一个std::string*,谁将删除它?如果你返回一个const std::string*,你几乎是在声明所有权,或者至少告诉调用方他们不负责。编译器不允许您删除常量指针。为什么投票被否决?这肯定会+1起作用,但一般来说,通过参数列表返回值不是一个好主意。@Ferrucio:同意。我当然会尽量避免这件事,但就像所有这些潜在的不可靠做法一样,如果所有其他方法都不起作用,它也有它的用处。这肯定会起到+1的作用,但一般来说,通过参数列表返回值不是一个好主意。@Ferrucio:同意。我当然会尽可能地避免这件事,但就像所有这些潜在的狡猾的做法一样,如果所有其他途径都不起作用,它也有它的用处。