这个简单的Message类是否可以使用智能指针?

时间:2013-01-30 18:00:14

标签: c++ oop pointers

我正在改变我当前的消息类实现:

class Message
{
public:
    Message(uint8* buffer, uint8 length) : m_contents(buffer), m_length(length) { }

    uint8 getLength() const {return m_length; }
    const uint8* getData() const { return m_contents; }
protected:
    uint8* m_contents;
    uint8 m_length;
};

在构造函数中只取长度,并在构造函数中动态分配,并在析构函数中删除。

我认为应该是这样的:

Message(uint8 length) : m_length(length)
{
    m_contents = new uint8[length];
}

~Message() 
{
    delete [] m_contents;
    m_contents = NULL;
}

附加信息:消息对象将被传递给将发送它的串行端口对象。它还将被子类化为多个CustomMessage类。

我的问题是:在这个简单的例子中,有没有理由使用某种类型的智能指针?一个例子会有所帮助。谢谢!

2 个答案:

答案 0 :(得分:2)

  

是否有任何理由使用某种类型的智能指针?

实际上这取决于。请考虑以下代码:

 Message m1 (1024);
 Message m2 (m1);

您希望m2成为m1的深层副本吗?您是否希望m1m2的基础缓冲区共享内存?或者你不希望副本开始(深或否)?也就是说,第二个语句应该导致编译错误?

  • 如果您希望他们共享内存,那么您应该使用std::shared_ptr
  • 如果你希望它们在内存中完全不同(深拷贝),那么不,你不应该使用shared_ptr;你可以使用std::unique_ptr,但你也必须实现copy-semantic。但是,如果你选择这种情况,那么最好使用std::vector<uint8>而不是实现你自己的类:

    typedef std::vector<uint8> Message;
    
    Message m1(1024);
    Message m2(m1); //m2 is a deep-copy of m1
    
  • 如果你想防止复制,因此第二个语句应该导致编译错误,那么你必须通过=deleteing禁用复制语义:

    Message(Message const &) = delete;
    Message& operator=(Message const &) = delete;
    

    请注意,在这种情况下,您必须自己实现移动语义。移动通常是有道理的,所以我不会对此发表评论。

希望有所帮助。

答案 1 :(得分:1)

关于复制和分配的政策是什么。如果你 使类不可复制,使用时没有真正的优势 智能指针。如果你支持深层复制,我不这么认为 有一个标准的智能指针可以完成这项工作;你会 必须自己实施副本和作业。或者使用 std::vector<char>,它将为您完成所有这些。如果你支持 浅拷贝,然后std::shared_ptr是完美的工作。

如果班级在施工后是不可移动的(如果是的话) 你已经展示了所有的成员),浅拷贝或没有拷贝是 要走的路。坦率地说,我可能只是使用std::stringstd::vector在这里,不用担心。它提供了深层复制 默认情况下,这可能是矫枉过正,但肯定是 最简单的解决方案