在派生类ctor中接收基类副本是否错误?

时间:2019-03-04 07:41:06

标签: c++ inheritance design-patterns

让派生类ctor在参数中接收基类的副本以避免避免在派生类ctor中再次重写所有基类ctor参数,这是一个不好的设计吗?

说你有

class CBase
{
public:
    int a1;
    int a2;
    int a3;

    CBase(int _a1, int _a2, int _a3) :
        a1(_a1), a2(_a2), a3(_a3)
    {}
};

class CDerived : public CBase
{
public:
    int b1;
    int b2;

    CDerived(int _a1, int _a2, int _a3, int _b1, int _b2) :
        CBase(_a1, _a2, _a3), b1(_b1), b2(_b2)
    {}
};

CDerived ctor似乎非常错误。在这种情况下,建议采取什么措施?我想将CDerived ctor更改为这样的内容:

class CDerived : public CBase
{
public:
    int b1;
    int b2;

    CDerived(CBase _cbase, int _b1, int _b2) :
        CBase(_cbase), b1(_b1), b2(_b2)
    {}
};

这是错吗?

2 个答案:

答案 0 :(得分:3)

这本身不是错。但是,这强烈表明该设计存在缺陷,尤其是其作者可能未正确应用composition over inheritance

使用一些不太抽象的伪代码来说明问题:

Rocket myrocket(1000); 
Booster mybooster1(200), mybooster2(200);

// should I really copy my rocket to add boosters ??? 
SuperRocket mynewrocket(myrocket, mybooster1, mybooster2); 

// or should I construct it with the boosters ? 
SuperRocket myrocket(1000, mybooster1, mybooster2);

// or should I make this more flexible
SuperRocket myrocket(1000);  
myrocket.add(mybooster1);
myrocket.add(mybooster2); 

答案 1 :(得分:-1)

您的第一种方法很好。没有错。但是,当参数数量超过5个时,建议使用构建器模式。

第二种选择没有意义。您间接地强迫派生类的调用者在构造函数中传入基类的对象。这是一个坏习惯,因为您在派生类中泄漏了基类的详细信息。

您应该坚持第一种方法。

相关问题