C++访问器 - 我应该返回成员变量的指针还是实际的成员变量本身?

3

我有一个希望相对简单的问题。对于我的类成员变量,它们全部都是私有的,我应该使用访问器返回指针还是返回变量本身?或者我应该做些其他的事情吗?

例如:

unsigned int *Object::GetObjectIDPointer()
{
    return &objectID;
}

或者

unsigned int Object::GetObjectID()
{
    return objectID;
}

3
最佳方法是避免访问器。 - Tadeusz Kopec for Ukraine
1
当函数返回非指针类型时,请不要将其命名为 GetXxxxPointer。 - harper
@harper 那只是我在提问时的一个小复制粘贴错误。>< - Interminable
2
你的第一个例子实际上将“private”变量公开了,这与“private”的目的相反。 - molbdnilo
4个回答

4
这取决于你想要用它们做什么:如果你计划允许类的用户修改类内变量(这是一件可怕且强烈不推荐的事情),则可以返回指针或引用;否则,返回变量本身。当你想要返回的对象很大(如向量、集合、映射等)时,有一个例外规则。如果你决定为它们创建访问器,则应通过常量引用返回它们。

1
我不同意。几乎从不应该返回成员指针,也不应该从getter函数中返回值。几乎总是应该返回引用和const引用。 - Mooing Duck
@MooingDuck 我遵循这个规则,在编写模板代码时返回引用,但在非模板代码中,我会根据具体情况做出决策。例如,出于纯粹的美观原因,我会通过值来返回 int,而不是通过常量引用。 - Sergey Kalinichenko

2

我建议选择第二种解决方案。
更一般地,你可以返回对象本身的副本,编译器很可能会通过复制省略优化来优化掉任何不必要的副本。

你也可以返回字段的const引用:

const MyType& getMyField() const { return this->myField; }

这样做,不会创建任何副本,值也无法被修改(除非使用const_cast)。

但是对于int类型,我认为你应该返回一个副本,就像你的第二个解决方案一样:

unsigned int Object::GetObjectIDPointer()
{
    return objectID;
}

返回引用可能是危险的。调用者可能会保存一个引用,例如 const MyType& m = something.getMyField();,这可能会导致悬空引用。 - Sebastian Mach
@phresnel:指针也有同样的问题,而且解决方法可能非常缓慢。通过引用返回是最好的选择。olchauvin:RVO仅在返回本地变量时有帮助。当返回成员时,仍然需要进行完整的复制。 - Mooing Duck
@MooingDuck 你说得对,我是指“复制省略”。我已经更正了回答。 - Mesop

1

如果您只想获取值,则通过值返回。此外,声明函数为const。但是,如果它很大或复制起来很昂贵,最好返回一个const引用,以便调用者可以选择不进行复制。

如果您还想修改它,则返回引用(或指针,如果您喜欢),或提供“设置”函数。或者,只需将其公开 - 当它不是封装时,假装它是封装的没有太多意义。

如果您返回引用(或指针),则确保您有一个const重载,否则您将无法从const对象中读取值:

const unsigned int *Object::GetObjectIDPointer() const
{
    return &objectID;
}

我不同意。几乎从不应该返回成员指针,也不应该从getter函数中返回值。几乎总是应该返回引用和const引用。 - Mooing Duck
@MooingDuck:这取决于类型,正如我所说的。返回小的POD类型(就像问题中的那个)通过值通常比通过引用更快且更安全;我建议使用引用而不是指针,但如果OP更喜欢指针,则不想指定样式。 - Mike Seymour

-1

这取决于你的方法。

GetObjectIDPointer() 

如果这是一个私有方法,那么使用指针会使成员访问更快。但是,如果这个方法是公共的,你应该始终返回一个副本。因为如果你返回一个指针,它将违反面向对象编程的基本原则(数据隐藏)。

2
在私有函数中通过指针返回成员变量是很愚蠢的。 - Mooing Duck

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