什么是getter方法的推荐签名?

时间:2012-10-25 12:45:14

标签: c++

假设需要实现getter / setter(我也尽量避免使用它们,因为它们通常表示设计不好)。以下两种变体哪种更好,每种变体的含义是什么?

可能性(1):

class Foo;
class Bar
{
public:
    const Foo& getFoo() const {return foo_;}
private:
    Foo foo_;
};

或(2):

class Foo;
class Bar
{
public:
    void getFoo(Foo& foo) const {foo = foo_}
private:
    Foo foo_;
};

就个人而言,我总是使用第一个变体,因为我发现它更直观。在第二个变体中,您必须在调用getFoo之前​​构造Foo对象,该对象将保存getFoo的结果,然后向getFoo传递对此对象的引用。这种变体对我来说是违反直觉的,但有些人更喜欢使用secodn变体。出于什么原因可能是第二个变体优于第一个?

3 个答案:

答案 0 :(得分:7)

输出论据应被视为刑事犯罪。它使用起来比较困难,但维护起来要困难得多,因为它在代码中不可见。如果指定了某些内容,则很清楚。如果在对象上调用了一个方法,那么它可能会修改它。但是如果它只传递给一个函数,那么普通的维护程序员就不会怀疑它被修改了。此外,大多数情况下,它需要额外的行来声明临时变量以接受该值。

这种事情主要是由那些停留在C89并以某种方式学习C ++语法的人写的。但是使用C ++ copy elision和C ++ 11的移动语义,我没有看到任何值得使代码更难阅读的正当理由。

当然,如果你要返回一个成员,你可以返回const引用。如果计算了这个值,只需按值返回,复制省略将在大部分时间内处理它。

答案 1 :(得分:0)

在一般情况下,第一变体当然是优选的。由于返回值优化(RVO),它的效率不低于秒,因为未复制返回的对象且没有性能开销。

如果您需要对传递的对象进行一些初步设置或使用某些部分副本,则第二个变体可能更为可取。但是,这当然不是一件轻而易举的事,而是一些不同语义的不同功能。

使用第二个变体的另一个可能原因 - 当传递对象时,不能由持有类直接创建,例如它的创建由一些工厂封装,你不想让你的类依赖于这个工厂。

答案 2 :(得分:0)

const Foo& getFoo() const {return foo_;}