C ++重载<<作为流的类对象的运算符

时间:2015-06-19 04:26:26

标签: c++ sockets tcp operators

所以我浏览了很多其他线程,但没有一个涉及我对这个确切主题的问题。我正在编写一个C ++库来进行套接字通信。我有一个TCP套接字类,它处理TCP套接字上的所有操作(设置,读/写等)。我希望能够使用<<<<<<<<<<<<<<和>>运营商。例如,我希望能够以这种方式将套接字写入套接字:

double x;
TcpSocket *sock = new TcpSocket();

//socket setup stuff here...

sock << x;

目前,我在TcpSocket类中有两个模板化的重载操作符函数:

template<typename T>
TcpSocket operator<<(TcpSocket sock, T &val)
{
    unsigned char bytesOfVal[] = //parse bytes of val here...

    sock.Write(bytesOfVal, sizeof(bytesOfVal));
}

-

template<typename T>
TcpSocket operator>>(TcpSocket sock, T &val)
{
    std::stringstream ss;
    byte buf[sizeof(val)];

    sock.Read(buf, sizeof(buf));
    ss.str(std::string(buf));

    ss >> val;
}

其中sock.Read()和sock.Write()使用套接字文件描述符(不是真正相关但只是FYI)发出系统调用read()和write()。这些函数是模板化的,试图能够在一个地方获得几乎任何数据类型的字节。

所以我的问题是:

  • 这些重载的操作符函数是否会以我希望的方式工作?
  • 如果有效,我可以将它们链接在一起,例如:

    袜子&lt;&lt; 45.8&lt;&lt; 33.9&lt;&lt; “数字”;

=============================================== ========================== 以下是我更新的操作员功能:

//Write to socket
template<typename T>
TcpSocket& operator<<(TcpSocket& sock, T &val)
{
    size_t buflen = sizeof(val);
    unsigned char buf[buflen];

    memcpy(buf, &val, buflen);

    sock.Write(buf, buflen);

    return sock;
}

//Read from socket
template<typename T>
TcpSocket& operator>>(TcpSocket &sock, T &val)
{
    size_t buflen = sizeof(val);
    unsigned char buf[buflen];
    int numBytesRead = 0;

    numBytesRead = sock.Read(buf, buflen);

    memcpy(&val, buf, numBytesRead);

    return sock;
} 

2 个答案:

答案 0 :(得分:2)

要使您的函数完全正常工作,您需要使用对TcpSocket的引用作为输入参数以及返回类型。另外val需要T const&,而不是T&

template<typename T>
TcpSocket& operator<<(TcpSocket& sock, T const&val)
{
    unsigned char bytesOfVal[] = //parse bytes of val here...

    sock.Write(bytesOfVal, sizeof(bytesOfVal));
    return sock;
}

现在,您可以使用:

sock << 45.8 << 33.9 << "numbers";

如果您还希望能够使用:

sock << 45.8 << 33.9 << "numbers" << std::endl;

你需要另一个功能。

TcpSocket& operator<<(TcpSocket& soc,
                      std::ostream&(*f)(std::ostream&))
{
    std::ostringstream s;
    s << f;
    return sock << s.str();
}

答案 1 :(得分:0)

您建议的代码

template<typename T>
TcpSocket operator<<(TcpSocket sock, T &val)
{
    unsigned char bytesOfVal[] = //parse bytes of val here...

    sock.Write(bytesOfVal, sizeof(bytesOfVal));
}

还有另一个重大缺陷(除了Sahu发出的信号之外):它会以二进制形式编写您的数据,并且会赢得人们对std :: ostream的期望。

例如

TcpSocket socket ;
socket << std::string("Hello") ;

不会写'你好'&#39;但有些不完善的数据(大小?指向实际文本的指针?取决于实现)。

我建议你编写自己的流buf。通过这种方式,您可以全部使用所有现有的std :: ostream东西。

std::ostream ost ;
ost.imbue(new my_sockect_streambuf) ;

//或std :: ostream ost(new my_socket_strembuf);     ost&lt;&lt; 1.2&lt;&lt; &#34;文本&#34; &LT;&LT; std :: endl;

您可以在此处找到参考资料:How do I create my own ostream/streambuf?(我认为您的问题几乎与此问题重复)或在此处:http://www.mr-edd.co.uk/blog/beginners_guide_streambuf

可能太多了,但我认为这是可行的方法。