初始化shared_ptr成员变量时:
// .h
class Customer
{
public:
  Customer();
private:
  std::shared_ptr<OtherClass> something_;
}
// .cpp
Customer():
  something_(new OtherClass())
{
}
与
Customer():
  something_(std::make_shared<OtherClass>())
{
}
是否允许使用make_shared版本?我似乎总是看到第一个版本,这是首选?
我发现了这篇文章,其中一个答案是@kerek SB说的
Run Code Online (Sandbox Code Playgroud)std::shared_ptr<Object> p1 = std::make_shared<Object>("foo"); std::shared_ptr<Object> p2(new Object("foo"));在你的代码中,第二个变量只是一个裸指针,而不是一个共享指针.
现在就肉了.make_shared(实际上)更有效,因为它在一个动态分配中将引用控制块与实际对象一起分配.相比之下,采用裸对象指针的shared_ptr的构造函数必须为引用计数分配另一个动态变量.权衡是make_shared(或其表兄allocate_shared)不允许您指定自定义删除器,因为分配是由分配器执行的.
(这不会影响对象本身的构造.从Object的角度来看,两个版本之间没有区别.更有效的是共享指针本身,而不是托管对象.)
现在我对这篇文章有两个问题,如果有人能澄清一下,我会很感激
为什么第二个不是共享指针?这不会增加引用计数
make_shared如何只进行一次内存分配,而new将两次内存分配,从而使make_shared更有效率?
对此有点澄清将不胜感激.
从 C++17 开始,您可以使用它make_unique来创建指向数组的智能指针,例如:
unique_ptr<int[]> ptr = make_unique<int[]>(10);
这将创建一个指向 10 个元素的数组的智能指针(事实上,将调用正确的 deleter[] 也很棒)。
然而,根据this make_shared不支持这样的功能(至少在 C++17 中不支持,据我所知):
shared_ptr<int[]> ptr = make_shared<int[]>(10);
上面的代码显然是非法的。事实上,我的 Visual Studio 2017 (v141) 吐出了以下错误:
C2070: 'int[]': illegal sizeof operand'
有趣的是,shared_ptr它本身确实支持数组类型(即shared_ptr<int[]>合法),但make_shared又不支持。然而make_unique确实如此。
问题是,是什么阻止了标准制定者支持make_shared数组类型,就像 的情况一样make_unique?
给定一个抽象接口和从该接口派生的实现,其中构造函数受到保护(这些对象的创建只能从类工厂中获得 - 实现DI模式),如何在工厂函数中使用make_shared?
例如:
class IInterface
{    
public:    
    virtual void Method() = 0;
};
class InterfaceImpl : public IInterface
{
public:
    virtual void Method() {}
protected:    
    InterfaceImpl() {}    
};
std::shared_ptr<IInterface> Create()
{
    std::shared_ptr<IInterface> object = std:: make_shared<InterfaceImpl>();    
    return object;
}
make_shared显然无法访问InterfaceImpl中的受保护构造函数,或者实际上是在IInterface中,给出了以下错误
error C2248: 'InterfaceImpl::InterfaceImpl' : cannot access protected member declared in class 'InterfaceImpl'
所以在这里阅读(问题:如何使boost :: make_shared成为我班级的朋友),我尝试将以下内容放入实现类中:
friend std::shared_ptr<InterfaceImpl> std::make_shared<InterfaceImpl>();
它仍然无法编译.那么我也将另一个放入IInterface类.仍然没有快乐.我在这做错了什么?
编辑:用于编译的完整源文件,与"朋友"...
#include <memory>
class IInterface
{    
public:    
    friend std::shared_ptr<IInterface> Create();     
    virtual void Method() = 0;
};
class …虽然我std::tr1::shared_ptr<T>在我的编译器中可用,但我没有make_shared.
有人能指点我正确实施make_shared吗?我看到我需要使用varargs为T的构造函数提供参数.
但是我的编译器中也没有可用的变量模板.
我有一个带有模板参数T的类模板Templ,而Templ类有一个类型为T的数据成员,称为obj.我编写了一个可变参数构造函数模板,它将参数转发给obj的构造函数:
template <class T>
class Templ
{
public:
     template <class... Args> explicit Templ (Args&&... args)
     : obj (std::forward<Args>(args)...)
     {
     }
private:
     T obj;
};
现在我意识到类型T可能是一个带有init-list构造函数的类,我希望它可以通过Templ访问.所以我检查了什么std::list::emplace,std::make_shared做了什么.它们具有像我一样的可变函数,但它们没有覆盖init-list的覆盖.由于某些原因.
所以第一个问题:为什么?我的意思是,如果我使用一个带有init-list ctor的类T,然后我用std::list<T>?为什么list ::\templates没有带初始化列表的版本?也许有一个很好的理由我应该这样做...所以我想知道.
此外,无论STL做什么 - 我应该提供一个init-list ctor作为好的设计吗?我的意思是,它就像可变的ctor,对吗?允许用户选择任何类型或种类的T,带TEMPL <>使用,并且直接调用为T.定义的任何构造函数即使它是一个构造函数采取一个init-列表.
有可能创建boost phoenix lazy变种std::make_shared吗?我的意思是,做一些类似的事情
namespace p = boost::phoenix;
...
expr = custom_parser[_a=p::make_shared<Node>(_1,_2,_3)] >> ...
BOOST_PHOENIX_ADAPT_FUNCTION由于可变模板的性质,人们无法使用std::make_shared.所以,如果有可能写一个包装器,那么包装器应该是variadic模板本身.
我是一个相对的C++新手,试图将现有项目从原始指针转换为使用复杂的内存管理协议,再转换为使用C++ 11 shared_ptr.总的来说它非常顺利,我想我理解shared_ptr移动语义,右值引用等方面是如何工作的.好东西.
但是,我遇到了一个奇怪的错误,我不明白,也不知道如何修复.先是一点背景.我有一个类层次结构,它以一个名为的抽象基类为根EidosValue,而一个名为EidosValue_Int_vector(间接)的类是它的具体子类:
class EidosValue
class EidosValue_Int : public EidosValue
class EidosValue_Int_vector : public EidosValue_Int
我的代码通常是流量EidosValue,但有时,特别是在创建新值时,我需要处理特定的子类.
我shared_ptr为这些类做了s的typedef ,所以我有:
typedef std::shared_ptr<EidosValue> EidosValue_SP;
typedef std::shared_ptr<EidosValue_Int_vector> EidosValue_Int_vector_SP;
等等.好的,所以现在问题的核心.我有一个函数返回EidosValue_SP它创建的.根据函数中的逻辑,它可能会创建几个不同的具体子类之一EidosValue.所以我这样做:
EidosValue_SP MyClass::MyMethod(...)
{
    EidosValue_SP result;
    if (...)
    {
        EidosValue_Int_vector_SP int_result_SP = make_shared<EidosValue_Int_vector>();
        ... do subclass-specific stuff with int_result_SP...
        result.swap(int_result_SP);
    }
    else (...)
    {
        ...similar logic for other subclasses...
    }
    ...other shared logic...
    return result;
}
问题出在swap() …
m_PhyToBtMap中SPacket中的shared_ptr似乎导致"大小为64的块内无效读取大小为8 - 40个字节".注意:在valgrind(下面的日志)发出此错误消息之前,这已经运行了近22个小时,有数百万条消息,但我也在EraseAcknowledgedPackets(下面)中遇到SIGSEGV崩溃,并怀疑这是原因.我使用的是Boost 1.63,因为交叉编译器不支持shared_ptr.在valgrind日志中调出SendMessageToBt(大小为8的无效读取)和EraseAcknowledgedPackets(大小为64的块中的40个字节).
SPacket和m_PhyToBtMap
typedef struct SPacket
{
    boost::shared_ptr<uint8_t[]> data;
    size_t size;
} SPacket;
map<uint16_t, SPacket> m_PhyToBtMap;
SendMessageToBt
void RadioManager::SendMessageToBt(uint8_t * response, size_t responseSize)
{
    CSrProtected ThreadSafe(m_LockPhyToBt);
    SPacket sentPacket;
    sentPacket.size = MESSAGE_HEADER_OFFSET + responseSize + CRC32_SIZE;
    sentPacket.data = boost::make_shared<uint8_t[]>(sentPacket.size);
    assert(sentPacket.data.get());
    memcpy(&sentPacket.data.get()[MESSAGE_HEADER_OFFSET], response, responseSize);
    m_AcknowledgementNumberSent = m_NextReceiveSequenceNumber;
    m_SequenceNumberSent = m_NextSendSequenceNumber;
    ++m_NextSendSequenceNumber;
    if (0 == m_NextSendSequenceNumber) m_NextSendSequenceNumber = SEQUENCE_NUMBER_MIN;
    m_PhyToBtMap[m_SequenceNumberSent] = sentPacket; // RadioManager.cpp:246
    sentPacket.data.get()[DATAGRAM_ACKNOWLEDGEMENT_LSB] = m_AcknowledgementNumberSent;
    sentPacket.data.get()[DATAGRAM_ACKNOWLEDGEMENT_MSB] = m_AcknowledgementNumberSent >> 8;
    sentPacket.data.get()[DATAGRAM_HEADER_SIZE + SEQUENCE_NUMBER_LIST_SIZE_LSB] = m_SequenceNumberSent;
    sentPacket.data.get()[DATAGRAM_HEADER_SIZE …我错过了一些东西std::make_shared。它不能解决 a 的类型std::initializer_list,还是我做错了什么?
#include <vector>
#include <memory>
class A {};
int main()
{
    A a;
    std::vector<A> veca{A(), A{}, a}; // this works ofc
    std::vector<A> vecb({A(), A{}, a}); // this too
    std::make_shared<std::vector<A>>(vecb); // and this, ofc
    std::make_shared<std::vector<A>>({a}); // what's wrong here?
    return 0;
}
错误:
main.cpp:21:41: error: too many arguments to function ‘std::shared_ptr<_Tp1> std::make_shared(_Args&& ...) [with _Tp = std::vector; _Args = {}]’
     std::make_shared<std::vector<A>>({a});
                                         ^
In file included from /usr/include/c++/6/memory:82:0,
                 from main.cpp:10:
/usr/include/c++/6/bits/shared_ptr.h:632:5: note: declared here
     make_shared(_Args&&... __args) …c++ ×10
make-shared ×10
shared-ptr ×4
c++11 ×3
boost ×2
constructor ×1
dictionary ×1
initializer ×1
pointers ×1
protected ×1
swap ×1
tr1 ×1
vector ×1