【问题标题】:Initializing a union初始化联合
【发布时间】:2011-05-24 18:29:48
【问题描述】:

之前的代码:

struct Inet_address{
char v4[4];
};
extern "C" Inet_address Inet_loopback = 
{
  {127,0,0,1}
};

修改后:

我已将 Inet_address 设为联合 这里Inet地址是一个联合

union Inet_address{
char v4[4];
char v6[16];
};

现在我想对 extern "C" Inet_address Inet_loopback 做同样的操作 说,

extern "C" Inet_address Inet_loopback = 
{
 if(some condition)
  {127,0,0,1}  //It should be Inet_address.v4
 else
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }  //This should be Inet_address.v6
};

请提出正确的方法来实现这一点,因为我在这里遇到错误。

【问题讨论】:

  • extern "C" 不是 C 语言的一部分。
  • @DeadMG...谢谢。其实我是新手。

标签: c++ ipv6


【解决方案1】:

您不应该为此使用 char 数组 - 将 in_addrin6_addr 合并:

typedef union {
    struct in_addr inaddr;
    struct in6_addr in6addr;
} in46_addr_t;

设置 ipv4 环回地址:

addr.inaddr.s_addr = INADDR_LOOPBACK;

对于 IPv6:

addr.in6addr = in6addr_loopback; // pre-defined global variable (note: assumes linux socket API)

【讨论】:

    【解决方案2】:

    bdonlan 的回答很好,但是如果您想要完全 POSIXly 可移植的东西,请参阅getaddrinfo()。 (好吧,无论如何,现代 POSIX。)

    struct addrinfo hints = { 0 };
    hints.ai_family = AF_INET6;
    hints.ai_flags = AI_NUMERICHOST;
    struct addrinfo *result = NULL;
    
    getaddrinfo("::1", NULL, &hints, &result);
    
    // result[0].ai_addr is now a pointer to the localhost IPv6 address as a sockaddr_in6
    // struct.
    
    freeaddrinfo(result);
    

    【讨论】:

      【解决方案3】:

      在我看来,这样的联合是没有意义的,因为Inet_address 会占用最大数组大小的内存。你为什么不只使用一个包含 16 个元素的数组?此外,如果您的条件只能在运行时评估,您将不得不将您的初始化放在一个函数中。如果可以在编译期间评估您的条件,那么您尝试做的事情可能可以使用模板和元编程来实现,但这并不简单,而且可能难以阅读。

      你能告诉我们更多关于你的情况吗?

      【讨论】:

      • @neodelphi...我想使用这个联合来设置 IPV4 和 V6 的环回地址。如果是 IPV4,我想填写 v4,如果是 IPV6,我想填写 v6
      • 是的,但是在这两种情况下,您都在内存中填充相同的字节。那个联合只会给你带来语法糖。
      【解决方案4】:

      由于您(显然,从附加到这个问题的标签来看)在这个项目中使用 c++,所以您根本不应该使用联合。 C 使用联合作为一种原始多态性。在 c++ 中,继承是可用的,并且是实现多态性的一种更健壮的方法。

      我建议您为此使用一个小的继承层次结构: (注意:这是框架代码,只是为了让您了解它是如何工作的)

      class Inet_address
      {
          vector<int> _address;
      
          public:
              Inet_address();
              virtual ~Inet_address();
      
              // pure virtual function...special behavior implemented in sub classes
              virtual vector<int> loopback() = 0;
      }
      
      class Inet_address_v4 : public Inet_address
      {
          public:
              Inet_address_v4();
              virtual ~Inet_address_v4();
      
              // special behavior for v4
              virtual vector<int> loopback();
      }
      
      class Inet_address_v6 : public Inet_address
      {
          public:
              Inet_address_v6();
              virtual ~Inet_address_v6();
      
              // special behavior for v6
              virtual vector<int> loopback();
      }
      
      int main()
      {
          // Create a new v4 address object
          Inet_address* my_v4_addr = new Inet_address_v4();
      
          // Create a new v6 address object
          Inet_address* my_v6_addr = new Inet_address_v6();
      
          vector<Inet_address*> addresses;
      
          addresses.push_back( my_v4_addr );
          addresses.push_back( my_v6_addr );
      
          // The loopback function is called in the same way for both sub-classes
          for( unsigned int i=0; i<addresses.size(); i++ )
          {
              Inet_address* curr_adr = addresses[i];
              curr_addr->loopback();
          }
      
          return 0;
      }
      

      这种方法一般是c++中使用的标准方法。这是一种非常强大的方法,因为它可以让您创建许多具有相似行为的不同类型的对象,这些对象都可以使用完全相同的函数调用进行操作。

      有关 c++ 继承的概述,请参阅此:http://www.cplusplus.com/doc/tutorial/inheritance/

      祝你好运!

      【讨论】:

        猜你喜欢
        • 2015-01-03
        • 1970-01-01
        • 1970-01-01
        • 2020-08-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多