3

I think have a good feel to this based on my research but would like confirmation. I've been learning about inheritance and how virtual methods work.

In the code at the bottom, I get the results (above code) when running main. If I switch the printType method to be the non-virtual, I instead get "AbstractClass" printing out.

As I understand it, using "virtual" indicates the method might be overwritten - and to always choose the "last reimplementation" of the method, in this case in ImplementationClass. My questions are:

1) Does this ALWAYS happen? Or are there instances where you may end up with the method from AbstractClass (or other classes, if it's inherited multiple times) being called even though it's a virtual method?

2) it seems you cannot instantiate a non-pointer of a class containing virtual methods. Is this true?

3) I am assuming there is nothing different in my two examples, but I'm only about 80% sure.

Many thanks for help, this whole virtual method thing is complicated to figure out from reading (which is why I created a dummy project in the first place!).

after redefinition 
ImplementationClass
printing from virtual method in ImplementationClass

second set of examples 
ImplementationClass
printing from virtual method in ImplementationClass

#include <iostream>
using namespace std;

class AbstractClass{

public:
    virtual void printStuff() = 0;
    AbstractClass() {};
    ~AbstractClass() {};

    virtual void printType() { std::cout << "AbstractClass" << std::endl; }
    // void printType() { std::cout << "AbstractClass" << std::endl; }

};
class ImplementationClass : public AbstractClass {

public:
    void printStuff() { std::cout << "printing from virtual method in ImplementationClass" << std::endl;}
    void printType() { std::cout << "ImplementationClass" << std::endl; }
    void printStuffOnlyInDerived() {std::cout << "printing from NONvirtual method in ImplementationClass" << std::endl;}


    ImplementationClass() {};
    ~ImplementationClass() {};
};




int main () {

    AbstractClass * absClass;
    ImplementationClass * impClass= new ImplementationClass;

    absClass = impClass;

    printf("\nafter redefinition \n");  
    absClass->printType();
    absClass->printStuff();


    AbstractClass * absClassNonPtrImpClass = new ImplementationClass;

    printf("\n second set of examples \n"); 
    absClassNonPtrImpClass->printType();
    absClassNonPtrImpClass->printStuff();


    return 0;
}
Xeo
  • 129,499
  • 52
  • 291
  • 397
enderland
  • 13,825
  • 17
  • 98
  • 152
  • No ,it doesn't always happen. When calling a virtual function in the constructor of a base-class and that function is not yet being overridden then the original function will be called. – engf-010 Jan 25 '12 at 00:13

3 Answers3

3
  1. Yes, you can explicitly specify the base-class method and call it, even through a pointer to a derived class (pDerived->Base::virtualMethod() -- this will call Base's implementation of virtualMethod()). You can also slice a derived-class object and lose polymorphism as well.

  2. You cannot create an object of a class with abstract methods (declared with = 0), but you can certainly create objects of classes with virtual methods that have implementations.

Community
  • 1
  • 1
mwigdahl
  • 16,268
  • 7
  • 50
  • 64
1

1) Yes, polymorphism always works.

2) You got it wrong, you can instantiate objects of the class in automatic storage.

The reason you can't in your example is because your base class is abstract.

This:

AbstractClass * absClass;

only declares a pointer to a base class. It doesn't create an actual object.

The following is legal:

ImplementationClass x;

Although ImplementationClass is a polymorphic type, you create an object in automatic storage (as opposed to what you call via a pointer). You can do this because abstract methods from the base class are implemented in the derived class.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • "2) You got it wrong, you can instantiate objects of the class in automatic storage." Ah, ok, your second example answers what I was goign to say. But, you cannot ever do AbstractClass* myAbsClass (if AbstractClass contains a virtual method? or is that only the case in mine since I have a pure virtual method?) – enderland Jan 24 '12 at 22:51
  • @enderland yes... so? - "2) it seems you cannot instantiate a non-pointer of a class containing virtual methods. Is this true?" It is not true, you can instantiate non-pointer (???) of a class containing virtual methods. – Luchian Grigore Jan 24 '12 at 22:53
  • @enderland `AbstractClass* myAbsClass` doesn't instantiate a class, it is just a pointer declaration. You can have a pointer declaration to an abstract class. What you can't do is create an instance: ` AbstractClass* myAbsClass = new AbstractClass;` will fail, as will ` AbstractClass myAbsClass;`. – Luchian Grigore Jan 24 '12 at 22:54
  • Even with virtual void printStuff() = 0; ? – enderland Jan 24 '12 at 22:55
  • @enderland **because** of virtual void printStuff() = 0. That's what makes the class abstract. Also, why the downvote? – Luchian Grigore Jan 24 '12 at 22:56
  • @enderland I know that, the question wasn't directed at you. But someone did. I have nothing against downvotes, but a comment would be nice so that I can learn from my mistakes... – Luchian Grigore Jan 24 '12 at 22:59
  • @Luchian Grigore: Polymorfism works only to the current construction level. When calling a virtual function in the constructor of a base-class and that function is not yet being overridden then the original function will be called. – engf-010 Jan 25 '12 at 00:36
  • @Edwin :| Polymorphism ALWAYS works. It's in the standard. Just because you haven't overriden a function, doesn't mean polymorphism doesn't work. – Luchian Grigore Jan 25 '12 at 07:26
  • @Luchian Grigore: I didn't say that it doesn't always work ,but it works to CURRENT level of construction. When you're in the constructor of a not most-derived class then the polymorfism can only work from the level you're currently in. When a virtual function is overridden in a higher level that function is not YET available and therefor a lower level override or the original function is called at that stage. – engf-010 Jan 25 '12 at 21:12
  • @Edwin are you actually explaining polymorphism? I see nothing wrong with my answer, if you do, please point out the exact part which you think is wrong. – Luchian Grigore Jan 25 '12 at 21:45
1

1) Does this ALWAYS happen?

Yes

Are there instances where you may end up with the method from AbstractClass (or other classes, if it's inherited multiple times) being called even though it's a virtual method?

Yes, if it isn't defined in the derived classes and doesn't = 0. If it is define in the derived classes, you may still call the base class's version with BaseClass::Method();

2) it seems you cannot instantiate a non-pointer of a class containing virtual methods. Is this true?

You can instantiate a class containing virtual methods but if they = 0 then it is abstract and you cannot.

Foggzie
  • 9,691
  • 1
  • 31
  • 48
  • Oh, cool, I didn't even know absClass->AbstractClass::printType(); would work – enderland Jan 24 '12 at 23:02
  • Yea, :: is the "scope resolution operator." – Foggzie Jan 24 '12 at 23:11
  • @Gunther Fox: No ,it doesn't always happen. When calling a virtual function in the constructor of a base-class and that function is not yet being overridden then the original function will be called. – engf-010 Jan 25 '12 at 00:31