Reputation: 69988
struct Base {
Base (type1, type2, type3);
Base (); // <--- should be invoked only by `Derived_2`
virtual ~Base() = 0; // an abstract class
};
Say for above Base
, we have multiple derived classes: Derived_1
, Derived_2
, ..., Derived_N
.
While constructing an object, all derived classes must invoke Base(type1, type2, type3)
constructor, except Derived_2
, which should use Base()
(the default constructor) while constructing the object.
Is there a way (C++11 is ok) to have such rule? In other words if anyone other than Derived_2
tries to use the default no argument constructor then compiler should give an error.
Edit: For those who are asking about the design problem, I agree with that. Here is my take on it.
type1, type2, type3
.main()
gets
executed. Naturally those are special cases and have to entertain
them by introducing a default constructorI hope this makes the idea clear.
Upvotes: 1
Views: 1141
Reputation: 422
When you are writing the derived classes, then in only the second derived class should you call the default base constructor in the rest you can call the parameterised constructor.
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){}
};
`
and so on. For the rest of the classes. Also... this is oop, you make the classes so you decide the behaviour of the classes yourself. Therefore you just make sure that the default constructor for base class isn't called anywhere in the derived classes explicitly. Everytime you need to call a constructor, you call the parameterised one in the derived classes, since afterall, you cnotrol the working of the class.
Upvotes: 0
Reputation: 5416
I would introduce another level of derivation:
Base
^
|
+-----+------+
| |
Derived2 BaseWithParams
^ ^
| |
Derived1 DerivedN
In the base, you implement no state or a default state (seems to me it makes sense to have a default state, since this is why Derived2
was supposed to do).
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
};
Upvotes: 4
Reputation: 3350
The only way I can think of is declaring your Base
's default constructor private and making Derived_2
a friend of your Base
class, so it can call its default contructor.
However, this style is horrible, since your Base
class now has to know about one of its derived classes. And it is still possible for Dervived_2
to call the constructor with 3 parameters.
Upvotes: 7
Reputation: 490178
Make the default constructor private, and declare Derived_2 as a friend:
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() {}
};
Upvotes: 2