C++ 如何向成员声明访问者?

C++ 如何向成员声明访问者?,c++,getter,C++,Getter,在一些类中,访问器被声明为getName1,而在另一些类中,访问器被声明为getName2。从使用角度来看,它看起来是相同的。在一个像样的编译器中,一个比另一个有任何性能优势吗?是否有任何情况下我应该只使用其中一个 class MyClass { public: MyClass(const string& name_):_name(name_) { } string getName1() const { return _name;

在一些类中,访问器被声明为
getName1
,而在另一些类中,访问器被声明为
getName2
。从使用角度来看,它看起来是相同的。在一个像样的编译器中,一个比另一个有任何性能优势吗?是否有任何情况下我应该只使用其中一个

class MyClass
{
  public:
    MyClass(const string& name_):_name(name_)
  {
  }
    string getName1() const
    {
      return _name;
    }
    const string& getName2() const
    {
      return _name;
    }
  private:
    string _name;
};

int main()
{
  MyClass c("Bala");
  string s1 = c.getName1();
  const string& s2 = c.getName1();
  string s3 = c.getName2();
  const string& s4 = c.getName2();
  return 0;
}
在这种情况下,编译器可以认真执行RVO(返回值优化)

在这种情况下,编译器可以认真执行RVO(返回值优化)

通过引用返回可能更快,因为不需要复制(尽管在许多情况下,该方法适用)

<>但是,它也增加了耦合性。考虑如果要更改类的内部实现,以便以不同的方式存储名称(即不再在<代码>字符串< /代码>中),会发生什么情况?。将不再有可通过引用返回的内容,因此您还需要更改公共接口,这意味着需要重新编译客户端代码。

通过引用返回可能更快,因为不需要进行复制(尽管在许多情况下,此方法适用)


<>但是,它也增加了耦合性。考虑如果要更改类的内部实现,以便以不同的方式存储名称(即不再在<代码>字符串< /代码>中),会发生什么情况?。将不再有可通过引用返回的内容,因此您还需要更改公共接口,这意味着需要重新编译客户端代码。

在上述四种情况下,它可能更快?
const string&s2=c.getName1();
这会创建任何副本吗?@balki:
const string&s2=c.getName1()
几乎肯定需要创建一个副本。首先,
s2
的refereand必须与
c.\u name
具有不同的地址。其次,如果
c.\u name
被另一位代码修改,则
s2
引用的字符串不能反映该更改。因此,除非编译器能够证明没有这样的更改nge发生时,如果您不做任何其他依赖于两者位于不同地址的事情,那么它就无法避免一个副本。要证明这一点很难,我认为编译器真的没有做太多努力。@Steve了解到了这一点。但它如何增加耦合?如果我选择更改内部实现,如果我返回副本或引用,它会产生怎样的影响?如果更改内部实现,内部可能不再有可通过引用返回的数据位。对于一个简单的示例,假设我们将
\u name
替换为
\u firstname
\u lastname
;现在需要计算
getName
的结果(通过连接字符串),因此无论如何都需要按值返回。如果从一开始就按值返回,则无需重新编译。在上述四种情况下,它可能会更快?
const-string&s2=c.getName1();
这会创建任何副本吗?@balki:
const-string&s2=c.getName1()
几乎肯定需要创建一个副本。首先,
s2
的refereand必须与
c.\u name
具有不同的地址。其次,如果
c.\u name
被另一位代码修改,则
s2
引用的字符串不能反映该更改。因此,除非编译器能够证明没有这样的更改nge发生时,如果您不做任何其他依赖于两者位于不同地址的事情,那么它就无法避免一个副本。要证明这一点很难,我认为编译器真的没有做太多努力。@Steve了解到了这一点。但它如何增加耦合?如果我选择更改内部实现,如果我返回副本或引用,它会产生怎样的影响?如果更改内部实现,内部可能不再有可通过引用返回的数据位。对于一个简单的示例,假设我们将
\u name
替换为
\u firstname
\u lastname
;现在需要计算
getName
的结果(通过连接字符串),因此无论如何都需要按值返回。如果从一开始就按值返回,则无需重新编译。我既不返回临时变量,也不返回本地堆栈变量,在这种情况下,编译器如何优化返回值
string s1=c.getName1()
?必须至少复制一份。@balki:显然,必须为
字符串s1=c.getName1();
,RVO只是表示它只有1份,而不是2份。同样,为
字符串s1=c.getName2()复制一份
。它们不同的情况是
std::如果我既不返回临时变量,也不返回本地堆栈变量,那么在这种情况下,编译器如何优化返回值
string s1=c.getName1();
?必须至少制作一个副本。@balki:显然,必须为
string s1=c.getName1()制作一个副本;
,RVO只是表示它只有1,而不是2。同样,为
字符串s1=c.getName2()制作了1个副本
。它们不同的情况是
std::cout它对用户来说不完全相同。如果
c.\u name
更改,则
s4
将给出新值,而其他将保留旧值。这对用户来说不完全相同。如果
c.\u name
更改,则
s4
将给出新值,而另一个值s将保留旧值。
string getName1() const
{
    return _name;
}