C++ 哪个是更好的获取成员方法?

C++ 哪个是更好的获取成员方法?,c++,class,vector,stdvector,accessor,C++,Class,Vector,Stdvector,Accessor,我有一个类,它的成员类型为std:vector private: std::vector<int> myVector; 1. const std::vector<int> GetMyVector() const; 2. const void GetMyVector(std::vector<int>& vec) const; 具体实现如下: 1. const std::vector<int> MyClass::Get

我有一个类,它的成员类型为
std:vector

  private:
     std::vector<int> myVector;
1. const std::vector<int>   GetMyVector() const;
2. const void   GetMyVector(std::vector<int>& vec) const;
具体实现如下:

1. const std::vector<int> MyClass::GetMyVector() const
   {
       return  myVector;
   }

2. const void MyClass::GetMyVector(std::vector<int>& vec) const
   {
       vec =  myVector;
   }
1。常量std::vector MyClass::GetMyVector()常量
{
返回myVector;
}
2.常量void MyClass::GetMyVector(std::vector&vec)常量
{
vec=myVector;
}
两种Get方法中哪一种更好?为什么?

我更喜欢选项3:

const std::vector<int>& MyClass::GetMyVector() const
{
    return  myVector;
}
常量std::vector&MyClass::GetMyVector()常量 { 返回myVector; }
您的选项1返回了
myVector
的副本。这将返回对类成员的常量(只读)引用。

为什么要返回向量

int MyClass::GetItem(const size_t index) const
{
    return myVector[index];
}

根据经验,始终尝试返回类成员的
const reference

因此,使用
const std::vector&MyClass::GetMyVector()const

如果通过复制返回对象,那么将其声明为const没有任何意义。所以不是

const std::vector<int> MyClass::GetMyVector() const
{
    return  myVector;
}
常量std::vector MyClass::GetMyVector()常量 { 返回myVector; } 我会写

std::vector<int> MyClass::GetMyVector() const
{
    return  myVector;
}
std::vector MyClass::GetMyVector()常量
{
返回myVector;
}
第二个声明比第一个声明更糟糕,因为它只会让用户感到困惑。不清楚是将类的相应数据成员指定给参数,还是此方法在未将相应数据成员指定给参数的情况下对参数进行了一些更改

因此,考虑到您建议的变体,我会选择声明

std::vector<int> MyClass::GetMyVector() const
{
    return  myVector;
}
std::vector MyClass::GetMyVector()常量
{
返回myVector;
}

首先,当您从成员函数返回类的私有成员时,您将公开您的实现,这通常是糟糕的设计。以@JoachimPileborg的解决方案为例,了解如何避免这种情况

如果要返回副本,则应按值返回

如果要返回对对象的引用,请按引用返回但是,请记住,当对象被破坏时,您将得到一个悬空引用,例如

class Foo {
public:
    std::vector<int>& getVec() {
        return myVec;
    }
private:
    std::vector<int> myVec;
};

int main() {
    Foo* f = new Foo();
    std::vector<int>& myRef = f->getVec();
    delete f;

    std::cout << myRef.size(); // The demons come! Dangling reference!
}
class-Foo{
公众:
std::vector和getVec(){
返回myVec;
}
私人:
std::载体myVec;
};
int main(){
Foo*f=新的Foo();
std::vector&myRef=f->getVec();
删除f;

std::第一个选项可以复制向量吗?这不是get的想法。第二个选项允许在函数调用后对myVector进行写访问…您希望调用方拥有自己的向量副本,还是希望调用方能够访问数据成员?@juanchopanza的目的只是访问成员。不需要复制。好的,两者都不需要您的方法正在这样做,所以它们都很差。@juanchopanza我想我应该选择Simonza,也许他们想返回一个副本。@simonc在某个地方我读到,如果函数的返回是聚合,那么应该通过引用输出参数而不是通过返回。这是真的吗?@onherocks不,这不是真的。@juanchopanza是真的,但我会发现t在这种情况下,函数名有点误导。想要拷贝的客户端不能通过
std::vector copy(myClass->GetMyVector());
?@emilogaravalia处理这个问题吗当然有不同级别的封装(假设引用的是数据成员)。引用和值是完全不同的东西。调用方无法通过引用修改数据的事实并不改变它们对可能更改甚至消失的内容的引用这一事实。避免添加
GetSize
Begin
End
,等等。德米特定律有时也会改进这完全取决于向量的用途,当然,“这通常是糟糕的设计”…这只是一种偏见。这里没有足够的背景来说明整体设计。@EmilioGaravaglia我不同意,设计原则是一种值得遵循的良好实践,特别是当你没有足够的经验来预见以后的问题时。设计原则是要在有限的背景下应用的,所以你可以抽象ur总体设计。在这种情况下,当类发生更改时(例如,容器类型的更改),公开实现会创建一个严格的设计将需要在使用该函数的所有其他类中进行更改。每个设计都可能是好的,也可能是坏的。设计原则不在信息论物理之外。有许多“模式”和许多“反模式”。其中一个反模式是“过度工程”:即使在上下文不需要的情况下,当一个原则被强制遵守时,也会发生这种情况。我们没有人能够评估上下文信息完全缺失。@EmilioGaravaglia因为我们谈论的是面向对象编程,而类不是聚合,暴露类的私有成员是一种反模式的指示问题是:你不应该这样做。我认为由于缺乏背景而称之为“过度工程”是一种根据你自己的经验得出的夸张,这不一定是给初学者的最佳建议。我之前的评论仍然适用。