首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >指针、引用还是智能指针?

指针、引用还是智能指针?
EN

Stack Overflow用户
提问于 2014-11-26 09:58:57
回答 2查看 143关注 0票数 2

我有以下问题:

让我们假设我有一个包含100个对象的向量,因此创建一个副本是很糟糕的。

代码语言:javascript
复制
class MyClass
{
 private:
 vector<MyObject> mVector;
};

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

vector<object>* MyClass::GetVector2()
{
 return &mVector;
};

通过引用返回是快速的,并没有生成副本。向量应该在MyClass中仍然可用,因此我不想移动它。但是,使用这个GetVector()方法的最佳方法是什么?

代码语言:javascript
复制
class MyOtherClass
{
 private:
    vector<MyObject>* myVector;
    vector<MyObject>& myVector2;
    vector<MyObject>  myVector3;

    MyClass m;
};

myVector2 = m.GetVector1(); //only works in an initializer list!

但是,如果在创建对象时无法初始化向量,怎么办?让我们假设我有一个OnInit()方法,它将在需要时被调用:

代码语言:javascript
复制
void MyOtherClass::OnInit()
{
 myVector = m.GetVector2(); //no copy using return by reference
 myVector = &m.GetVector1(); //no copy returning a pointer
 myVector3 = m.GetVector1(); //copy
}

很多人告诉我使用像myVector这样的指针是很糟糕的,但是为什么?我应该用smart_pointers代替吗?(请给我一个例子,如何使用上面给出的代码)

或者有更好的方法来获得快速的表现?

编辑:

对于这个答案,请检查下面所选的答案。

此外,我想添加移动语义。

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

如果您不再需要返回的对象,并且它可能会被销毁,那么您可以使用“按值返回”,这是可以的,因为编译器可能会通过移动来优化它,但是您可以显式地使用movesemantics并将向量移出类,因为向量元素是动态分配的,容器是可移动的。检查此链接:Is returning by rvalue reference more efficient?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-11-26 10:05:14

公共物品是可以的

在这一点上只有一个公共目标。你不需要那个吸气剂

代码语言:javascript
复制
struct X {
    std::vector<Y> vec;

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

然后,您可以简单地将其用作:

代码语言:javascript
复制
X x(..);
x.vec.some_member_function();

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

如果你真的需要

如果您确实需要使用成员函数版本,那么就使用reference,这有点习以为常,尽管它基本上与按指针返回性能相同:

代码语言:javascript
复制
vector<Y>& X::GetVector() {
    return mVector;
}

然后将其用作:

代码语言:javascript
复制
X x(..);
x.GetVector().some_member_function();

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

智能指针不适用于此。

智能指针解决了处理资源和描述所有权的问题。在这种情况下,考虑到std::vector已经在内部拥有和处理自己的资源,它们就没有什么意义了。

票数 3
EN

Stack Overflow用户

发布于 2014-11-26 10:52:32

如果myVector可以由初始化程序列表初始化,那么就执行它!否则你必须使用指针。

指针并不坏,它们只是没有引用那么严格。如果myVector接受nullptr/0值,则可以使用指针。当您使用引用时,它会告诉您它不会是null (或者至少不应该是),并且当您想要使用它时,您不需要检查myVector == 0是否是空的。

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

vector<object>* MyClass::GetVector2()

意味着该函数可能返回nullptr/0,而

vector<object> & MyClass::GetVector2()

不可能。

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

关于你的设计。如果可以通过MyClass::mVector函数访问GetVector(),为什么要初始化引用?另外,你真的需要这样的访问吗?如果MyClass能够维护与mVector相关的所有内容,那就更好了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27146103

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档