2016-08-11 42 views
-5
class myMem{}; 

class Test{ 
public: 
    initMem1(myMem& mInput){/*initialize _mem1*/} 
    initMem2(shared_ptr<myMem> &pmInput){/*initialize _mem2*/} 

    myMem _mem1; 
    shared_ptr<myMem> _mem2; 
}; 

Test myTest; 
myTest() 

因此,在上面的代码中,成员属于一个类。一个成员是一个值类型,另一个成员是shared_ptr类型。对于班级成员来说哪种方式更好?此外,我还有初始化成员的功能。哪种方法更好?直接通过引用传递给shared_ptr的好处是,通过引用直接传递

一般来说,通过引用传递给shared_ptr而不是直接传递引用的优点是什么?

+4

...一个需要你有'shared_ptr'? – GManNickG

+3

这个问题应该是:“通过引用传递'shared_ptr'而直接传递给'shared_ptr'的优点是什么?”答案是:它更便宜。 – tkausl

+0

对于编译器来说,它们都是不同的类型。你不能真正比较苹果和橘子。 **'测试**和**'shared_ptr **不一样*参考类型*。至于从后者获得前者的性能成本,其可能仅仅是额外间接成本。但后者提供了更多的信息 – WhiZTiM

回答

1

原因函数应该接受一个std::shared_ptr的说法是,如果它可能需要共享或修改资源的所有权。如果不是,请不要通过std::shared_ptr

如果功能肯定需要共享所有权,那么它应该接受值为std::shared_ptr。如果该功能可能会或可能不会共享所有权,则只接受std::shared_ptr&

如果函数不修改所有权然后通过一个参考的资源,而不是一个std::shared_ptr

参见:CppCoreGuidelines:F.7R.30R.34R.35

0

一个用例是原始shared_ptr可以在函数中间更改其内容(可能是嵌套调用),并且函数已准备好并且需要新内容。

1

让我们来看看你的函数中。对于initmem1,代码通常看起来像

initMem1(myMem& mInput){ _mem1 = mInput; } 

我们可以看到一个赋值操作符,通常会将所有myMem领域的召唤。

对于initMem2,有两种情况

1)

initMem2(shared_ptr<myMem> &pmInput){ 
    _mem2 = pmInput; 
} 

你应该用 'initMem2(常量的shared_ptr & pmInput)'。这是一个很好的风格。 我们可以在这里看到快速初始化。只有链接被复制。但是你获得了所有权共享。如果您在外面更改pmInput,则_mem2也会更改。 不需要复制cunstructor。两个智能ptrs都拥有独特的对象。

2)

initMem2(const shared_ptr<myMem> &pmInput){ // of course, const 
    _mem2.reset(*pmInput); 
} 

您创建新内容的新的shared_ptr最初来自pmInput复制。 您可以独立更换pmInput_mem2。但是,对于这个新的shared_ptr和复制构造函数调用,您会获得额外的“新/删除调用”。