C ++:从基类实例构造子类?

时间:2010-06-25 21:18:50

标签: c++ struct

我有三个结构,其中一个继承自另外两个结构:

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;

(我希望第三个结构包含前两个的所有成员。有更好的方法吗?)

现在,我已经完全填充了ABCDEF的实例,我想创建一个新的ABCDEF实例:

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
}

创建ABCDEF的最佳方法是什么?我能做到这一点,但它有点糟糕:

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;

以上与结构的成员相关联,如果添加了许多成员,则会很混乱。

3 个答案:

答案 0 :(得分:8)

这是C ++。那些typedef不是必需的。你有建设者:

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

答案 1 :(得分:4)

  

我希望第三个结构包含前两个的所有成员。有没有更好的方法呢?

让第三个结构包含另外两个的实例是否可行? (如果这是“has-a”关系而不是“is-a”,也可能更合乎逻辑。)

struct ABCDEF
{
    ABC abc;
    DEF def;
};

当然,这会改变您访问和使用这些成员的方式。但是,如果您可以这样做,那么它会打开几种简单的方法来初始化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 };

否则,如果你确实需要从其他两个继承ABCDEF,那么我通常会从sbi的答案中推荐你添加适当构造函数的概念。虽然取决于您的确切需求,但可以使用聚合初始化和生成的复制构造函数来简化它。

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

答案 2 :(得分:0)

如果您打算使用C ++,那么您应该使用C ++构造,包括构造函数等。如果你想采用C方式,只需使用C构造(组合而不是继承,顺便提一下这是一个很好的建议:总是喜欢组合继承)。

然后,通过使用强制转换来利用编译器生成的赋值运算符,有一个丑陋的技巧(不推荐,但可行):

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

这是一个真的,真的,真的丑陋的答案。只是编写它来指出static_cast派生对象到基类是什么意思:它生成一个类型base的引用,引用该base的子对象部分,包括多继承发挥作用时所需的偏移量。请注意,如果使用了reinterpret_cast,则两个分配都将覆盖ABC实例的ABCDEF子对象。