开发者

Initializing a union

Previous code :

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

After modifying:

I have made Inet_address a union Here Inet address is a union

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

Now I want to do the same operation on extern "C" Inet_address Inet_loopback Say,

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 开发者_JS百科be Inet_address.v6
};

Please suggest a correct way to acheive this as I am getting error here.


You shouldn't use char arrays for this - make a union out of in_addr and in6_addr:

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

To set an ipv4 loopback address:

addr.inaddr.s_addr = INADDR_LOOPBACK;

For IPv6:

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


bdonlan's answer is good, but if you want something totally POSIXly portable, see getaddrinfo(). (Well, modern POSIX, anyway.)

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


In my opinion it does not make sense to have such union, since Inet_address would take in memory the size of the biggest array. Why don'y you use only one array of 16 elements ? Furthermore, you will have to put your initialization in a function if your condition can only be evaluated during runtime. If your condition can be evaluated during compile time, may be what you try to do could be achieved using templates and metaprogramming, but it won't be simple and it may be hardly readable.

Could you tell us more about your condition ?


Since you are (apparently, judging by the tags attached to this question) using c++ for this project, you should not use a union at all. C used unions as a sort of primitive polymorphism. In c++ inheritance is available, and is a much more robust method of implementing polymorphism.

I would recommend that you use a small inheritance heirarchy for this: ( Note: this is skeleton code that is only meant to give you an idea of how this might work)

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

This approach is generally the standard method used in c++. It is a really powerful approach, because it can allow you to create many different types of objects with similar behavior that can all be manipulated using the exact same function calls.

See this for an overview of c++ inheritance: http://www.cplusplus.com/doc/tutorial/inheritance/

Good luck!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜