pure virtual function

learningunix
learningunix used Ask the Experts™
on
I have an application of this type:

                   A (usually has all pure virtual function ) Abstract Class
                    |
             ____|____
             |               |
            B              C

In main Program,
A objA;
onjA.display()

where display() is pure virtual in A and then defined in B and C

Everytime I want to add a new method specific to class "C", I have to define that as virtual function in abstract class "A" which is fine. The problem is I have to define that in "B" also (even though it will never be used) because B is also derived from abstract class A
Compiler fails saying some methods are pure virtual in A and needs to be defined.

is there a way I can overcome this of not defining in B?

         
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
>> I have to define that as virtual function in abstract class "A"
I guess that you "have  to define that as virtual function in abstract class A" because you are using class A as your interface to the rest of classes that use class C.

The way you have structured your organization, then you must have a do-nothing method in class B to mirror the pure virtual function that you added in A.

Author

Commented:
yeah unfortunately its the design issue. right now as a workaround i just declare the methods in B.h but don't define them in B.cpp.  This solves my problem but unfortunately as i keep adding methods in C I have to unnecessary declare in B.h

 

Author

Commented:
also I declared mirrored those unwanted virtual functions in B.h as private so that at least it can't be called by others
CompTIA Security+

Learn the essential functions of CompTIA Security+, which establishes the core knowledge required of any cybersecurity role and leads professionals into intermediate-level cybersecurity jobs.

Author

Commented:
oops the compilation worked but while running the program it failed, looks like I'll have to define those in B.cpp
There may be an abstract class design issue lurking since you are defining pure virtual methods that are not required for all the derived classes.There are multiple approaches to avoid having to write useless methods in the derived classes.    You may need another higher layer of abstraction to capture what is truly common.    For those methods that are not required by all the derived classes, just make them virtual rather than pure virtual.    You can define multiple abstract classes having all pure virtual methods and use each one as the interface to the user classes.         -- You can even have multiple inheritance of pure abstract classes without having to be concerned about the diamond of death.                 http://en.wikipedia.org/wiki/Diamond_problem   
>> A objA;Usually if the class is a pure abstract class having pure virtual methods, then you cannot instantiate the class; so I'm not sure from your description, how you were able to get this LOC to compile.Perhaps you should post your code (or at least a buildable/runnable pruned version) to illustrate your description.
Try to code this to illustrate the above points.

       A           A has pure virtual m1
        |
    --------
    |       |
   A1    A2    A1 has pure virtual m2; A2 has pure virtual m3


class B : public A1 {...}
class C : public A2 {...}
class D : public A1, public A2 {...}


learningunix,

Ask yourself why you are adding a pure virtual method inside A if you do not want to have to define it inside B.
"generalization" relation (the one which link B and C to A) can be interpreted as "is a" relation between two classes, i.e. B is a A object, so MUST share all the access methods and member variables with A. No way.
Why one should define a method inside A instead of C only? because that methods is an attribute of A, like "mewing" is an attribute of cats and "barking" of dogs. Let's say that "cocker" and "retriever" are subclasses of dogs. If you add "wagging the tail" to the dog class, you can't expect that this attribute will not transfer to  cocker and retriever classes.
So you have two options:

1) adding method m to A is wrong because m is not an attribute of the class A. This is why you do not want to implement m in B.

or

2) m is an attribute of A, so you must implement it in B.

In the latter case, you can avoid implementing each new method in B and C by defining a default method to A. This way A is not really a "pure abstract" class, but it is abstract because there are some method that is pure virtual. This default method could for example throw an exception when the method is called from a class that do not redefine it - but in my opinion it's a wrong design. There are many better design for this.

There are many other solution to your problem, but your question is too general to describe one that fit to your needs.
Commented:
You're facing Liskov principle... in fact, in your original design, you've considered that both 'C' and 'B' are 'A', but now realize that either one or another are not really 'A'.
IIt's quite difficult to give an appropriate answer as we're not aware of your design constraints.
But if you can, I would suggest to proceed as this :
A1 --
|       |
A    B
|
C

> Just move all real common C & B members into A1, and let the rest into A

If it's more appropriate regarding your design, you can also proceed as this :

A ---
|       |
A1    B
|
C

> Just move all real common C& B members into A, and let the rest into A1. If, in you're existing code, you have always considered that both B and C can be handled as A, it would be the better solution.




Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial