简体   繁体   中英

A Method that returns “const std::string&” with error checking

I am writing a function, which I want to return "const std::string&". Let's just look at the codes.

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

The above codes are an example. The basic idea is to write a function that returns const reference, but also able to check for errors.

So, how to get around "return "Warning!";"?

Thanks,

if (list.empty()) {
    static std::string w("Warning!");
    return w;
}

since you're returning a const reference, it does not matter that you're always returning a reference to the same object.

If you're interested in using string references, why not take a string reference as a parameter and return a Boolean success/failure flag?

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

Achieves same result, and gives a simple Boolean result.

EDIT: as Ferruccio points out, this isn't an approach to be taken lightly. Use of parameters for output in this manner is prone to causing confusion and bugs, and should be used sparingly, and be well documented where used.

If you really want to avoid using exceptions (that would be my first choice), you may consider this:

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

You might throw an exception in this function and add a function to check whether the list is empty. Then the caller can check before calling GetString() . But if they fail to do that, they get an exception they can't ignore.

If you don't want to use exceptions (there are pros and cons of going either way), I'd first ask if it's reasonable to require the caller to call an "isValid" method first.

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

If it were me, I'd probably have it return a const std::string* instead so NULL is an option, or define a sentinel value as Fiktik suggested.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM