C++ 在构造函数中声明类变量

问题描述 投票:0回答:1

我可以在类中以两种不同的方式初始化shared_ptr。(以增加use_count为条件)。

1.方式

class MyClass {
    std::shared_ptr<std::string> s1;
public:
    MyClass(std::shared_ptr<std::string>& s2): s1{s2} {}
};

2.方式

class MyClass2 {
    std::shared_ptr<std::string> s1;
public:
    MyClass2(std::shared_ptr<std::string> s2): s1{std::move(s2)} {}
};
int main() {
    std::shared_ptr<std::string> s2 = std::make_shared<std::string>("Hello World");
    MyClass myClass {s2};
    MyClass2 myClass2 {s2};
    
    std::cout << "Use count:" << s2.use_count() << std::endl;
        
    return 0;
}
Use count:3

我用的是第一种方式的参考。我用的是第二种方式的move。

我认为第二种方式比第一种方式没有任何优势。 我认为永远不应该使用第二种方式,因为有一个额外的移动操作。

从性能角度来看,你认为哪种方式定义shared_ptr更好?

c++ smart-pointers
1个回答
3
投票

第一种方式需要至少有一个

shared_ptr
的副本(从
s2
s1
),无论调用函数做什么,这需要抓取锁、递增和递减引用计数以及其他开销。 另外,由于第一个版本需要一个
shared_ptr&
,那么如果调用函数有一个临时
shared_ptr&&
,那么他们将被迫在构造类之前将其存储在变量中:

    std::shared_ptr<std::string> s2 = std::make_shared<std::string>("Hello World");
    MyClass myClass {s2};

第二种方式允许调用者将

shared_ptr
值移动到构造函数中,然后将其直接移动到
s1
中。移动操作更便宜:它们不需要锁,并且不增加或减少引用计数。他们的速度快得离谱。此外,由于第二个只接受一个值,因此可以以任何方式构造它,因此可以直接从临时变量构造:

    MyClass myClass {std::make_shared<std::string>("Hello World")};

所以第二种方式在各方面都更优越。

© www.soinside.com 2019 - 2024. All rights reserved.