返回 &const 还是 *const?(C++)

5

我有自己的类"SomeObject",其中包含一些成员。

现在,我有另一个类"WorkingClass",该类将此对象作为私有成员。

我的问题是:我想为"SomeObject"创建Getter,但我不希望任何人修改它。

哪种方法更好,1还是2?

1. 返回对象的const指针或引用,这样调用者只能读取对象,不能修改它。

2. 返回一个副本,调用者可以随意修改副本,但原始对象保持不变。

class WorkingClass
{
private:
    SomeObject sObj;

public:
    //... 1)
    const SomeObject &const GetSomeObject()
    {
        return mousePosition;
    }

    //... 2)
    const SomeObject *const GetSomeObject()
    {
        return &mouseMovement;
    }
}

我知道你总是可以放弃const,但我只是试图让我的代码更加清晰和安全。
编辑:
那么我有一个进一步的问题。当我有一个智能指针成员并在类内部频繁使用它,然后突然想要让其他人读取一些值但不做其他操作时,这是否是一个好的解决方案,还是又过于冗长?
class X
{
private:
    boost::shared_ptr<SomeObject> sob

public:
    const const & GetSomeObject()
    {
        return *sob.get();
    }
}

还有一个问题,如果返回 "const boost::shared_ptr<...> GetX()" 呢?这可能不是真正必要的,但仍然不是无用的,因为在这种情况下编译器会禁止使用 GetX().reset(..),如果没有 const boost::... 声明,则允许执行此无用操作。我的理解是否正确?


好的,因为someobject是一个相当大的类。我只想把它传回去,以便其他人可以访问一些值。 - cppanda
通过值返回对象通常是安全的,因为每个现代编译器都实现了RVO和NRVO。担心这一点是过早优化。 :) - jalf
2个回答

7

两种方式都不好:

  • const SomeObject &const是不合法的。你无法为引用添加const限定符。(当然,你可以为引用所指类型添加const限定符。)

  • const SomeObject *const过于冗长。函数调用表达式o.GetSomeObject()是一个rvalue表达式,只有类类型rvalues可以被const限定。你可以直接使用const SomeObject*。(尽管const SomeObject *const可能会导致模板实例化问题,但这种问题很少见。)

至于你选择返回指针还是引用,取决于你如何使用返回值。在不同情况下,两者都可以有意义。无论如何,你需要返回一个指向const对象的引用或指针,而不是一个const引用或指针:

const SomeObject& GetSomeObject() { ... }
const SomeObject* GetSomeObject() { ... }

通常情况下,返回引用更为可取。

1
@cppanda:如果不需要指针,使用引用。指针很少被需要。 - James McNellis
每个引用都是常量引用。因此,const SomeObject &constconst SomeObject&相同。在我看来,最好通过引用返回。 - Pawel Zubrycki
然后我有一个进一步的问题。当我在类内部有一个智能指针成员并且经常使用它,然后突然想让某人只读取一些值而不做其他操作时,这是否是一个好的解决方案,还是又显得啰嗦了?类X { private: boost::shared_ptr<SomeObject> sob;public: const const & GetSomeObject() { return *sob.get(); } } - cppanda

5

& const 是无意义的。引用始终是常量。省略那里的 const 关键字。

如果您想返回一个常量的非空对象,则使用引用更好。如果要返回对象或空指针,则使用指针。

另请参阅 我何时应该使用引用,何时应该使用指针?

尽可能使用引用,必须使用指针。

每当您不需要“重新设置”时,通常优先使用引用而不是指针。这通常意味着在类的公共接口中最有用。引用通常出现在对象的外部,指针则出现在内部。

上述规则的例外是函数的参数或返回值需要“哨兵”引用-不引用任何对象的引用。这通常最好通过返回/获取指针并将 NULL 指针赋予此特殊意义来完成(引用应始终别名对象,而不是取消引用的 NULL 指针)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接