Reputation: 2854
Consider the following:
class base {
// base class
public:
void doBaseStuff() {
/* do something basic */
}
private:
int someDataMember;
};
class derived : public base {
// this class inherits 'doBaseStuff()' as well as 'someDataMember'
public:
void doDerivedStuff() {
/* do something in addition that only this type of derived class can do */
}
};
class specialDerived : public base {
// say 'doBaseStuff()' doesn't make sense in the context of this class!
// we do not want to inherit that function here
// is there a way to prevent instances of this class from calling it?
// we still want 'someDataMember', so we must derive from the base class
public:
void doSpecialStuff() {
/* do something in addition that only this special derived class can do */
}
};
There's a class that serves as a common base class for multiple other classes. But let's say one of the base class' member functions it NOT wanted in one of the derived classes. Is there a way to explicitly ban an inherited function in a derived class?
Realisticly we could be talking about a base class that has a 1000 members, and we want to inherit 999 of them, so simply abandoning inheritance and just duplicating all the code will result in very bad code maintainability.
Making that function in the base class virtual, and providing a dummy implementation of it in the specialDerived
class would work. But what if that function has an actual return type, instead of void
? The specialDerived
class would then have to provide an implementation that returns something. The caller then could assume that the value they got is something meaningful, when it's really not, and that's a problem.
Simply implementing the virtual function in specialDerived
with a single throw
in the body could be a solution, as long as some documentation exists that explicitly states that calling this function on objects of this specific derived type has no meaning, and that this operation will throw. I think this is one possible solution, but I'm not sure if it's the best way to go.
Upvotes: 3
Views: 1511
Reputation: 6447
doBaseStuff
protected in base
base2
from base
which just makes doBaseStuff
publicbase2
instead of base
base
Like so:
class base {
protected:
void doBaseStuff() {
/* do something basic */
}
private:
int someDataMember;
};
class base2 : public base {
public:
using base::doBaseStuff; // make it public
};
class derived : public base2 {
// ...
};
class specialDerived : public base {
// doBaseStuff not public here since we're derived only from base (and not base2) and didn't make it public ourself
};
Upvotes: 1
Reputation: 1372
I'm assuming you just want to make sure the method is not called accidentially, i.e. a compilation error when it gets called is perfect.
You can simply override doBaseStuff
in specialDerived
with a deleted definition:
class specialDerived : public base {
void doBaseStuff() = delete;
public:
void doSpecialStuff() {
/* do something in addition that only this special derived class can do */
}
};
That will prevent anyone from using specialDerived::doBaseStuff
. It is still possible to convert a reference to specialDerived
to a reference to base
and call doBaseStuff
on the result, but that can't be avoided without making doBaseStuff
virtual
.
Upvotes: 2