C++ 指针、引用还是智能指针?

C++ 指针、引用还是智能指针?,c++,pointers,reference,return,C++,Pointers,Reference,Return,我有以下问题: 假设我有一个包含100个对象的向量,因此创建一个副本是不好的 class MyClass { private: vector<MyObject> mVector; }; //return by reference vector<object>& MyClass::GetVector1() { return mVector; } vector<object>* MyClass::GetVector2() { return &a

我有以下问题:

假设我有一个包含100个对象的向量,因此创建一个副本是不好的

class MyClass
{
 private:
 vector<MyObject> mVector;
};

//return by reference
vector<object>& MyClass::GetVector1()
{
 return mVector;
}

vector<object>* MyClass::GetVector2()
{
 return &mVector;
};
很多人告诉我使用myVector这样的指针非常糟糕,但为什么????? 我应该改用智能指针吗?(请给我一个例子,如何在上面给定的代码中使用它们)

或者有没有更好的方法来获得快速性能

编辑:

有关答案,请在下面检查我为此选择的答案

此外,我想添加移动语义

但这在很大程度上取决于代码的用途,有时你真的想复制,你将无法避免它。如果您知道对象的持续时间比跟踪它的代码的持续时间长,那么只要您也希望应用更改,指针就可以了,否则请使用const ref

如果您不再需要返回的对象,并且它可能会被破坏,那么您可以使用按值返回,这是可以的,因为编译器可以通过移动对其进行优化,但是您可以显式地使用movesemantics并将向量移出类,因为向量元素是动态分配的,容器是可移动的。检查此链接:

公共对象正常 在这一点上,只有一个公共对象。你不需要那个getter:

如果你真的需要 如果您真的需要使用成员函数版本,那么就使用引用返回,这有点惯用,尽管它与指针返回在性能方面基本相同:

vector<Y>& X::GetVector() {
    return mVector;
}
智能指针不适用于此
智能指针解决了处理资源和描述所有权的问题。在这种情况下,如果
std::vector
已经在内部拥有并处理自己的资源,它们就没有多大意义了。

如果
myVector
可以通过初始值设定项列表初始化,那么就这样做吧!否则,您必须使用指针

指针并不坏,它们只是比引用限制更少。如果接受
myVector
的null ptr/0值,则可以使用指针。当您使用reference时,它告诉您它不会为null(或者至少不应该为null),并且您不需要在想要使用它时检查
myVector==0

我对返回值应用相同的约定。比如对我来说,像这样的声明

vector*MyClass::GetVector2()

表示函数可能返回null ptr/0,而

vector&MyClass::GetVector2()

不能


要安全地使用指针或引用,您必须确保
MyClass
对象比
MyOtherClass
对象寿命长。在您的示例中,它是满意的,因为
MyClass
对象是
MyOtherClass
的成员



现在谈谈你的设计。如果可以通过
GetVector()
函数访问
MyClass::mVector
,为什么要初始化引用?还有,你真的需要这样的访问吗?如果
MyClass
能够维护与
mVector

相关的所有内容,那就更好了。不要将智能指针视为指针,而是从所包含指针的所有权角度来看待它们。为什么不请告诉您的人详细说明呢?因此我必须使用指针或引用,但原始指针不坏吗?@slei:如果你试图用它们来管理所有权,或者指向可能被破坏的东西,它们就坏了。如果你只是想指向比指针寿命更长的东西,它们也不错。在其他论坛上,有人告诉我,这样的指针可能会导致意外的错误,这应该是一个更好的解决方案:(使用无容器的示例)
std::shared\u ptr\u test;const std::shared_ptr&GetTest()const{return_test;}
但是如果向量应该在整个类中可用呢?@slei在这两种情况下,向量在整个类中都可用。你的确切意思是什么?为了使z在整个类中可用,我将把它放在header:中,然后在.cpp中初始化它,但是使用引用变量只允许在构造函数中使用初始值设定项列表来初始化它。第二个带getter的方法不仅仅是惯用的,它提供了一种非常有用的方法来跟踪将来对此变量的访问。您可以在Get方法上粘贴断点,或进行一些快速状态验证,以后您不可能轻易地对公共成员进行更改。@slei在所有示例中
z
只是对存储在类外部某处的向量的引用
x
也是类
x
的一个实例。在我的示例中,您可以使用标识符
vec
访问类中的向量。人们总是告诉我避免使用此类指针,因为它们会导致意外错误,并询问原因。如果使用得当,它们不会导致意外的错误。从来没有得到任何正确的答案,为什么它们会导致错误,这就是为什么我现在感到困惑:)@slei-read
void MyOtherClass::OnInit()
{
 myVector = m.GetVector2(); //no copy using return by reference
 myVector = &m.GetVector1(); //no copy returning a pointer
 myVector3 = m.GetVector1(); //copy
}
struct X {
    std::vector<Y> vec;

    X(..) : vec(..) { .. }
};
X x(..);
x.vec.some_member_function();

auto& z = x.vec;
z.vec.some_member_function();
vector<Y>& X::GetVector() {
    return mVector;
}
X x(..);
x.GetVector().some_member_function();

auto& z = x.GetVector();
z.some_member_function();