tags:

views:

73

answers:

3

I have three structs, one of which inherits from the other two:

typedef struct _abc
{
    int A;
    int B; 
    int C;
} ABC;

typedef struct _def
{
    int D;
    int E;
    int F;
} DEF;

typedef struct _abcdef : ABC, DEF { } ABCDEF;

(I want the third struct to contain all the members of the first two. Is there a better way to do it?)

Now, I have fully populated instances of ABC and DEF, and I want to make a new ABCDEF instance:

int main()
{
    ABC abc;
    abc.B = 2;
    abc.C = 1;
    abc.A = 10;

    DEF def;
    def.D = 32;
    def.E = 31;
    def.F = 90;

    // make a new ABCDEF with all the values of abc and def
}

What is the best way to create the ABCDEF? I could do this, but it kinda sucks:

ABCDEF abcdef;
abcdef.A = abc.A;
abcdef.B = abc.B;
abcdef.C = abc.C;
abcdef.D = def.D;
abcdef.E = def.E;
abcdef.F = def.F;

The above is coupled to the members of the structs, and is messy if many members are added.

+8  A: 

This is C++. Those typedefs aren't needed. And you have constructors:

struct abc {
    int A;
    int B; 
    int C;
    abc(int a, int b, int c) : A(a), B(b), C(c) {}
};

struct def {
    int D;
    int E;
    int F;
    def(int d, int e, int f) : D(d), E(e), F(f) {}
};

struct abcdef : abc, def {
  abcdef(const abc& a, const def& d) : abc(a), def(d) {}
};

int main()
{
   abc a(2,1,10);
   def d(32,31,90);
   abcdef ad(a,d);

   return 0;
}
sbi
+4  A: 

I want the third struct to contain all the members of the first two. Is there a better way to do it?

Would it be feasible to make your third structure contain instances of the other two? (It may also be more logical if this is a "has-a" relationship instead of a "is-a".)

struct ABCDEF
{
    ABC abc;
    DEF def;
};

Of course, this changes exactly how you access and use those members. However, if this is possible for you, then it opens up several simple ways to initialize ABCDEF.

ABC abc = { 10, 2, 1 };
DEF def = { 32, 31, 90 };

// Assign members from preexisting variables.
ABCDEF abcdef1;
abcdef1.abc = abc;
abcdef1.def = def;

// Initialize aggregate using preexisting variables.
ABCDEF abcdef2 = { abc, def };

// Initialize the entire aggregate in one statement.
ABCDEF abcdef3 = { 10, 2, 1, 32, 31, 90 };

Otherwise, if you do need to have ABCDEF inherit from the other two, then I would generally recommend concept from sbi's answer where you would add the appropriate constructors. Though depending on your exact needs, it might be possible to simplify it a little making use of aggregate initialization and generated copy constructors.

struct ABC
{
    int A;
    int B;
    int C;
};

struct DEF
{
    int D;
    int E;
    int F;
};

struct ABCDEF : public ABC, public DEF
{
    ABCDEF(const ABC& abc, const DEF& def) : ABC(abc), DEF(def) {}
};

int main()
{
    ABC abc = { 10, 2, 1 };
    DEF def = { 32, 31, 90 };
    ABCDEF abcdef(abc, def);

    return 0;
}
TheUndeadFish
A: 

If you are going to use C++, then you should use the C++ constructs, including constructors and such. If you want to go the C way, just use C constructs (composition instead of inheritance, which by the way is a good advice: always prefer composition to inheritance).

Then, there is an ugly trick (not recommended, but feasable) by using casts to make use of the compiler generated assignment operators:

ABC abc = { 1, 2, 3 };
DEF def = { 4, 5, 6 };
ABCDEF o = {};
static_cast<ABC&>(o) = abc;
static_cast<DEF&>(o) = def;

And this is a really, really, really ugly answer. Just wrote it to point out what static_cast-ing a derived object to a base class means: it generates a reference of type base that refers to that base's subobject part, including the offset required when multiple inheritance comes into play. Note that if reinterpret_cast had been used instead, both assignments would be overwritting the ABC subobject of the ABCDEF instance.

David Rodríguez - dribeas