如何将unique_ptr <char []>传递给要使用的函数

nck*_*ner 2 c++ pointers visual-c++ c++11

这基本上就是我想做的事情:

SerialPort::ReadBytes(int32& errcode, Message::string& msg, uint32 num)
{
    DWORD numBytesRead = 0;
    LPDWORD pNumBytesRead = &numBytesRead;
    errcode = 0;        

    std::unique_ptr <char[]> buff (new char[num]);
    // ^^^^ pass this char buffer to the ReadFile function below

    if (!ReadFile(m_sp_pointer,     // Handle to device
            buff,                  // Receives data from device
            num,                    // num bytes to read (in)
            (LPDWORD)pNumBytesRead, // num bytes read (out)
            NULL))
        {
            errcode = GetLastError();
        }

    if (numBytesRead > 0)
    {
        return true;
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

我知道我没有正确地做到这一点,所以我的问题是:我如何正确地做到这一点,有什么能让这个想法变得糟糕吗?提前致谢.

编辑:我实际上应该在参数中传递unique_ptr而不是在本地声明它并传入Message::string& msg.

我最初的尝试是通过引用传递Message::string(std::string),所以这也是一个选项..即,而不是使用unique_ptr.在这种情况下,我会char[]在本地使用常规,然后将msg内容设置为char[]并返回它.

我不确定哪个更好,似乎有很多回复建议vector<char>.(与使用非常相似std::string).

Naw*_*waz 7

我觉得你不需要std::unique_ptr.std::vector在这种情况下我更喜欢:

std::vector<char> buff(num);    //and pass buff.data() to function
                                //which accepts char*

if (!ReadFile(m_sp_pointer,               // Handle to device
        buff.data(),                      // Receives data from device
        buff.size(), //(CHANGED THIS TOO) //num bytes to read (in)
        (LPDWORD)pNumBytesRead,           // num bytes read (out)
        NULL))
    {
        errcode = GetLastError();
    }
Run Code Online (Sandbox Code Playgroud)

请注意,std::vector::data()仅适用于C++ 11.在C++ 03中,您可以使用&buff[0].

  • "unique_ptr <char []>"的一个优点是,它不会不必要地初始化即将被覆盖的数据. (3认同)
  • @Nawaz,在std :: unique_ptr上优先选择vector的原因是什么? (2认同)

Dan*_*iel 5

使用智能指针很好,非常有用,但有些情况下原始指针是正确的选择.

我的猜测是ReadFile使用缓冲区并且不将它存储在任何地方 - 因此没有真正的参数用于具有该功能的智能指针.只需将原始指针与

buff.get()
Run Code Online (Sandbox Code Playgroud)

进一步评论: ReadFile 之外
使用unique_ptr是有意义的,因为它可以帮助正确处理内存.使用"手动内存管理",您需要在从函数返回的每个路径上删除(例如,异常).