2011-05-24 100 views
1

以前的代码:初始化工会

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]; 
}; 

现在我想这样做对外部“C”的操作Inet_地址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 
}; 

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

+0

'extern“C”'不是C语言的一部分。 – Puppy 2011-05-24 18:40:50

+0

@DeadMG ...谢谢。其实我对这个很陌生。 – 2011-05-24 18:41:56

+3

第一个提示:C!= C++。 – Puppy 2011-05-24 18:45:45

回答

5

你不应该使用字符数组这个 - 做一个工会出来的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) 
1

在我看来,拥有这样的联盟没有任何意义,因为Inet_address会占用最大阵列的大小。为什么你只使用一个16个元素的数组?此外,如果只能在运行时评估条件,则必须将初始化放入函数中。如果您的条件可以在编译期间进行评估,可能是您尝试使用模板和元编程可以实现的目标,但这不会很简单,并且可能很难读取。

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

+0

@neodelphi ...我想用这个联合来设置IPV4和V6的环回地址。在IPV4的情况下,我想填写第4版和IPV6的情况下,我想填写v6 – 2011-05-24 18:48:34

+0

是的,但是在这两种情况下,您都在内存中填充相同的字节。这个联盟只会给你带来语法糖。 – neodelphi 2011-05-24 22:08:55

1

既然你是(显然,通过标签附加到这个问题)使用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/

祝你好运!

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);