返回“NULL引用”在C ++? [英] Returning a "NULL reference" in C++?

查看:175
本文介绍了返回“NULL引用”在C ++?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在JavaScript或PHP等动态类型语言中,我通常会执行以下函数:

In dynamically typed languages like JavaScript or PHP, I often do functions such as:

function getSomething(name) {
    if (content_[name]) return content_[name];
    return null; // doesn't exist
}

我返回一个对象,如果它存在或 null 如果没有。

I return an object if it exists or null if not.

在C ++中使用引用会有什么等价?一般有任何推荐的模式吗?我看到一些框架有 isNull()方法为此目的:

What would be the equivalent in C++ using references? Is there any recommended pattern in general? I saw some frameworks having an isNull() method for this purpose:

SomeResource SomeClass::getSomething(std::string name) {
    if (content_.find(name) != content_.end()) return content_[name];
    SomeResource output; // Create a "null" resource
    return output;
}

然后调用者以这种方式检查资源:

Then the caller would check the resource that way:

SomeResource r = obj.getSomething("something");
if (!r.isNull()) {
    // OK
} else {
    // NOT OK
}

然而,为每个类实现这种魔法似乎很重。此外,当对象的内部状态应该从null设置为not null时,它似乎不明显。

However, having to implement this kind of magic method for each class seems heavy. Also it doesn't seem obvious when the internal state of the object should be set from "null" to "not null".

这个模式有什么替代方法吗?我已经知道它可以使用指针,但我想知道如何/如果它可以做参考。或者我应该放弃在C ++中返回null对象和使用一些C ++特定模式?

Is there any alternative to this pattern? I already know it can be done using pointers, but I am wondering how/if it can be done with references. Or should I give up on returning "null" objects in C++ and use some C++-specific pattern? Any suggestion on the proper way to do that would be appreciated.

推荐答案

您不能在引用期间执行此操作,因为它们不应该空值。基本上有三个选项,一个使用指针,其他的使用值语义。

You cannot do this during references, as they should never be NULL. There are basically three options, one using a pointer, the others using value semantics.


  1. 当调用者有一个指针时,资源不会被破坏;还要确保调用者知道它不需要删除对象):

  1. With a pointer (note: this requires that the resource doesn't get destructed while the caller has a pointer to it; also make sure the caller knows it doesn't need to delete the object):

SomeResource* SomeClass::getSomething(std::string name) {
    std::map<std::string, SomeResource>::iterator it = content_.find(name);
    if (it != content_.end()) 
        return &(*it);  
    return NULL;  
}


  • 使用 std :: pair 用一个 bool 来指示该项目是否有效(注意:要求SomeResource有一个适当的默认构造函数,并且构建起来不昂贵):

  • Using std::pair with a bool to indicate if the item is valid or not (note: requires that SomeResource has an appropriate default constructor and is not expensive to construct):

    std::pair<SomeResource, bool> SomeClass::getSomething(std::string name) {
        std::map<std::string, SomeResource>::iterator it = content_.find(name);
        if (it != content_.end()) 
            return std::make_pair(*it, true);  
        return std::make_pair(SomeResource(), false);  
    }
    


  • 使用 boost :: optional

    boost::optional<SomeResource> SomeClass::getSomething(std::string name) {
        std::map<std::string, SomeResource>::iterator it = content_.find(name);
        if (it != content_.end()) 
            return *it;  
        return boost::optional<SomeResource>();  
    }
    


  • 语义和有能力使用Boost,我推荐选项三。 boost :: optional over std :: pair 的主要优点是统一的 boost :: optional value不构造其封装的类型。这意味着它适用于没有默认构造函数的类型,并且为具有非平凡默认构造函数的类型节省了时间/内存。

    If you want value semantics and have the ability to use Boost, I'd recommend option three. The primary advantage of boost::optional over std::pair is that an unitialized boost::optional value doesn't construct the type its encapsulating. This means it works for types that have no default constructor and saves time/memory for types with a non-trivial default constructor.

    我也修改了你的示例,不用两次搜索地图(通过重复使用迭代器)。

    I also modified your example so you're not searching the map twice (by reusing the iterator).

    这篇关于返回“NULL引用”在C ++?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆