Reputation:
Say you have a base class with multiple functions, like
virtual int func1();
virtual int func2();
virtual int func3();
virtual int func4();
etc.
And you want to have two child classes, Child1 and Child2. Can Child1 contain func1() and func2() but not func3() or func4(), while Child2 contains func3() and func4() but not func1() or func2()?
So Child1 would contain:
int func1()
int func2()
And Child2 would contain:
int func3()
int func4()
I'm asking because I'm trying to do something like this, but when I try to run it, I keep getting undefined reference errors all over the place. For instance, there will be an error like:
/tmp/cczUiDZ2.o:(.rodata._ZTV5Child1[_ZTV5Child1]+0x38): undefined reference to `Parent::func3()'
Upvotes: 1
Views: 125
Reputation: 33116
Say you have a base class with multiple functions, like
virtual int func1();
virtual int func2();
virtual int func3();
virtual int func4();
There's a potential problem already, even without mentioning the derived classes. You've declared Base::func1()
, etc., but you haven't defined those functions. That's what the linker error was complaining about.
If it doesn't make sense to define those functions at the base class level, you need to declare those functions as "pure virtual" by inserting = 0
before the semicolons that terminate the function declarations:
class Base {
public:
virtual int func1() = 0;
virtual int func2() = 0;
virtual int func3() = 0;
virtual int func4() = 0;
...
};
(Note: I made those pure virtual functions public on purpose. I'll get to that later.)
What this does is to say that those functions can be used on any class that derives from the base class, but at the same time, it doesn't make sense to define those functions at the base class level. If you do this, those functions must be defined in the child classes (or in the sub-child classes, or the sub-...-sub-child classes). A class with undefined pure virtual functions is not instantiable.
What if you want Child1
to have functions func1()
and func2()
, but not func3()
or func4()
? The functions are callable at the base class level, but not at the child class level. This violates the Liskov substitution principle. This is a very big sign that your design is wrong.
An alternative is to provide default implementations at the base class level (where that makes sense), and override them at the child class level (where this makes sense). Your Child1
can provide class-specific definitions of func1()
and func2()
that override the defaults provided in the base class.
Yet another alternative is to use multiple inheritance. Multiple inheritance can get you in deep trouble, but done right, there's nothing wrong with multiple inheritance.
Yet another alternative is to do something that subverts but does not violate Liskov substitution. For example, implement func3()
and func4()
in Child1
, but always throw an exception in these implementations. Don't do this.
Upvotes: 1
Reputation: 36086
You cannot achieve what you literally asked, i.e. a child class not "having" a function of a base class while another child is having it. However, from your example, I see that you might mean something different. Let's look at the example below:
class Parent
{
virtual int func1() = 0;
virtual int func2()
{ return 0; }
};
class Child: public Parent
{
int func1()
{ return 0; }
};
int main()
{
Child c;
}
In this example, class Child
does not override the virtual func2
. However, you can see that the Parent
class provided its own definition that will be used as "default" in this case.
Upvotes: 0