如何使基类的某些构造函数只能由特定的派生类调用?

时间:2013-05-01 06:39:41

标签: c++ inheritance c++11 constructor

struct Base {
  Base (type1, type2, type3);
  Base (); // <--- should be invoked only by `Derived_2`
  virtual ~Base() = 0;  // an abstract class
};

对于上述Base说,我们有多个派生类:Derived_1Derived_2,...,Derived_N

构造对象时,所有派生类都必须调用Base(type1, type2, type3)构造函数,Derived_2除外,它应该在构造对象时使用Base()(默认构造函数)。

有没有办法(C ++ 11可以)有这样的规则?换句话说,如果Derived_2以外的任何人尝试使用默认的无参数构造函数,那么编译器应该给出错误。

编辑:对于那些询问设计问题的人,我同意这一点。这是我的看法。

  • 其实理想情况下我根本不需要默认的构造函数。所有 必须使用带有运行时的争论构造函数 参数形式为type1, type2, type3
  • 现在,我在继承层次结构中看到了几个类 在main()获得之前,对象将被全局实例化 执行。当然,这些是特殊情况,必须娱乐 它们通过引入默认构造函数
  • 然而,这种治疗仅适用于1或2类。休息一下 类必须维护调用争论构造函数的规则。

我希望这会让这个想法变得清晰。

4 个答案:

答案 0 :(得分:7)

我能想到的唯一方法是将Base的默认构造函数声明为私有,并使Derived_2成为Base类的朋友,这样它就可以调用默认的构造函数。 / p>

然而,这种风格很糟糕,因为你的Base类现在必须知道它的一个派生类。 Dervived_2仍然可以使用3个参数调用构造函数。

答案 1 :(得分:4)

我会介绍另一个推导级别:

        Base
         ^
         |
   +-----+------+
   |            |
Derived2    BaseWithParams
              ^         ^
              |         |
           Derived1    DerivedN

在基础中,你没有实现状态或默认状态(在我看来,有一个默认状态是有道理的,因为这就是Derived2应该这样做的原因。)

struct Base
{
    virtual ~Base() = 0;
};
struct Derived2 : public Base
{
    Derived2() {}          // Do default initialization
    virtual ~Derived2() {} // Implement destructor so it's not pure virtual anymore
};
struct BaseWithCtor : public Base
{
    BaseWithCtor(type1, type2, type3) {}
    // Do not implement destructor, leave the class abstract
};

答案 2 :(得分:2)

将默认构造函数设为私有,并将Derived_2声明为朋友:

class Derived_2;

class Base { 
    Base();
public:
    Base(int, int, int);
    virtual ~Base() = 0;
    friend class Derived_2;
};

class Derived_1 : public Base { 
public:
    Derived_1() : Base(1, 2, 3) {}
};

class Derived_1a : public Base { 
public:
    Derived_1() {} // will fail: Base::Base() not accessible
};


class Derived_2 :public Base { 
public:
   ~Derived_2() {}
};

答案 3 :(得分:0)

在编写派生类时,如果只在第二个派生类中调用默认的基本构造函数,则可以调用参数化构造函数。

      class derived1{             
                     derived1(): base(type1, type2, type3){}

                     };

       class derived2{
                      derived2(): base(){}
                      };
        class derived3{             
                     derived3(): base(type1, type2, type3){}

                     };
       class derived4{             
                     derived4(): base(type1, type2, type3){}

                     };

`

等等。对于其他课程。另外......这是oop,你创建课程,这样你就可以自己决定课程的行为。 因此,您只需确保未在派生类中的任何位置显式调用基类的默认构造函数。 每次你需要调用一个构造函数时,你都会在派生类中调用参数化的一个,因为毕竟,你可以调用类的工作。