2011-05-24 101 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);