【问题标题】:Defining a new data-type that behaves like a standard c++ data-type定义行为类似于标准 c++ 数据类型的新数据类型
【发布时间】:2014-05-04 22:32:45
【问题描述】:

在我的程序中,我想为 IPAddressV4 定义一个新的数据类型,为此我定义了以下类:

#include <boost/array.hpp>
#include <boost/asio.hpp>

#include "archive.hpp"

using boost::asio::ip::address_v4;
typedef boost::uint8_t     uint8;   /**< 8-bit unsigned interger.   */

class IPAddrV4
{
public:
/**
 * Construct a IPAddrV4 data type.
 */
IPAddrV4() : _ip_address(0)
{}


/**
 * Construct a IPAddrV4 data type.
 *
 * @param ip_address The value of the IPv4 Address in text format.
 */
IPAddrV4(std::string ip_address) : _ip_address(0)
{
    *this = ip_address;
}

/**
 * Set the IPv4 Address value.
 *
 * @param val The value of the IPv4 Address in text format.
 * @return The reference to the IPAddrV4 data type.
 */
IPAddrV4& operator=(std::string ip_address)
{
    boost::asio::ip::address_v4::bytes_type bytes
            = boost::asio::ip::address_v4::from_string(ip_address).to_bytes();

    _ip_address = ((uint32(bytes.at(0)) << 24) |
                   (uint32(bytes.at(1)) << 16) |
                   (uint32(bytes.at(2)) <<  8) |
                    uint32(bytes.at(3)));

    return *this;
}

IPAddrV4& operator=(uint32 ip_address)
{
    _ip_address = ip_address;
    return *this;
}

/**
 * Get the IPv4 Address data type value.
 *
 * @return The IPv4 Address data type value in binary form.
 */
operator uint32()
{
    return _ip_address;
}

private:
    uint32 _ip_address;

};

稍后我将使用这个类进行一些序列化和反序列化,以通过 TCP 连接发送数据。 当我使用输出存档进行序列化时,我没有任何问题。

IPAddrV4 ip("127.0.0.1");
oarchive & ip;

在上面的示例中,IP 的值被转换为二进制形式,然后复制到输出存档中。 oarchive 将增加 4 个字节。

但是当我尝试将此数据类型与输入存档一起使用进行序列化时,我遇到了问题:

IPAddrV4 ip;
iarchive & ip;

这是我在编译时遇到的错误:

No match for 'operator&' in 'input_Archive & IPAddrV4::operator uint32()'

那么我在 IPAddrV4 中缺少什么?

注意:输入存档与标准 c++ 数据类型(如 uint、string..等)完美配合。

【问题讨论】:

  • 一个观察:您正在根据赋值编写构造函数。不要那样做,效率太低了。用构造函数然后是交换来写你的赋值。
  • 我不确定我的理解是否正确,你能解释一下为什么它效率低吗?
  • 构造函数将在第一个“{”之前完全初始化所有成员。您的构造函数执行此操作,然后调用 *this = ip_address,这会调用对赋值运算符的调用。实际上,它为成员变量赋值两次。

标签: c++ serialization boost


【解决方案1】:

【讨论】:

  • 所以@sehe,我的问题是因为我没有重载运算符?我应该使用 BOOST_STRONG_TYPEDEF 来完成这项工作,对吗?
  • 我没有使用 Boost 的存档,抱歉我应该提到这一点。我有自己的输入和输出存档类。那么 BOOST_STRONG_TYPEDEF 对我仍然有效吗?
  • 强类型定义在前端工作(为你的类选择序列化实现),而不是后端,所以你很好。
  • 我现在尝试为我的数据类型BOOST_STRONG_TYPEDEF (IPAddrV4, IPADDRESS) 做,但我得到了同样的错误。可能是我弄错了
  • 呃。如果您想“定义一个行为类似于标准 c++ 数据类型的新数据类型”(请参阅您的问题标题),那应该只是 BOOST_STRONG_TYPEDEF(uint32_t, IPADDRESS)。当然,当你只是 typedef 已经不工作的类型时,它会 /still/ not-work :)
【解决方案2】:

我发现错误,我必须将运算符uint32()的重载更改为uint32&amp;(),如下所示:

operator uint32 &()
{
    return _ip_address;
}

通过这种方式,我通过引用而不是输入存档的值返回值。

【讨论】:

  • 是的,就是这样。一个非常常见的提升序列化问题:S
猜你喜欢
  • 2023-02-23
  • 1970-01-01
  • 1970-01-01
  • 2012-04-21
  • 2021-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多