Thread: Polymorphism in C++

  1. #1
    Registered User
    Join Date
    Jul 2011
    Posts
    22

    Question Polymorphism in C++

    I have been using C++ for a long time now, but this just blows my mind. For my example I made two classes: A and B. Class A was meant to be the interface, where B is a child of A that contains the actual commands. In hope that I could use polymorphism besides the scope of an argument into a function/method, I went ahead and tried shoving and instance B into A.

    I was not sure that this would work in the first place which is why I did this test. But that is not the full purpose of this post. What really blew my mind was the output (of the non-pointer version)! It returned 1! But my mind is trying to connivence itself that the outputs should either be an error or to return 5.

    The pointer method works just as expected. But I would very much rather use the non-pointer method if at all possible.

    Code:
    #include <iostream>
    
    using namespace std;
    
    class A
    {
    public:
    	virtual int yay(){return 5;}
    };
    class B : public A
    {
    public:
    	int yay(){return 1;}
    };
    
    int main (int argc, const char * argv[])
    {
    	A val = B();
    	cout << val.yay() << endl << endl;
    	A *valp = new B();
    	cout << valp->yay() << endl << endl;
    	return 0;
    }
    Thanks for any help!

    ==Short Version==
    1) Whats up with the output?
    2) How can I fix it?

  2. #2
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    You need polymorphism tutorials...

    In a nutshell, the class keeps track of its virtual methods at runtime, as opposed to compile-time, thus even if a superclass's pointer is used, the correct method is being called.
    Devoted my life to programming...

  3. #3
    Registered User
    Join Date
    Jul 2011
    Location
    Godthåb, Grønland
    Posts
    9
    Yep, it all has to do with virtual methods. Since your vtable points to B::yay(), you get a "1" when you call valp->yay(). This is just the nature of polymorphism.

    If you want to call A's yay(), you can explicitly call it with valp->A::yay().

  4. #4
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    But I would very much rather use the non-pointer method if at all possible.
    You can't. Polymorphism only works through indirection.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    If it helps anything, it works with references, as well.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Registered User gardhr's Avatar
    Join Date
    Apr 2011
    Posts
    151
    Quote Originally Posted by jakebird451 View Post
    I have been using C++ for a long time now, but this just blows my mind. For my example I made two classes: A and B. Class A was meant to be the interface, where B is a child of A that contains the actual commands. In hope that I could use polymorphism besides the scope of an argument into a function/method, I went ahead and tried shoving and instance B into A.

    I was not sure that this would work in the first place which is why I did this test. But that is not the full purpose of this post. What really blew my mind was the output (of the non-pointer version)! It returned 1! But my mind is trying to connivence itself that the outputs should either be an error or to return 5.

    The pointer method works just as expected. But I would very much rather use the non-pointer method if at all possible.

    Code:
    #include <iostream>
    
    using namespace std;
    
    class A
    {
    public:
    	virtual int yay(){return 5;}
    };
    class B : public A
    {
    public:
    	int yay(){return 1;}
    };
    
    int main (int argc, const char * argv[])
    {
    	A val = B();
    	cout << val.yay() << endl << endl;
    	A *valp = new B();
    	cout << valp->yay() << endl << endl;
    	return 0;
    }
    Thanks for any help!

    ==Short Version==
    1) Whats up with the output?
    2) How can I fix it?
    Your first output can't possibly be '1' - the variable 'val' is of type A..initializing it with an object of type B does nothing to the vtable. It might help to keep in mind that C++ requires that the size of a stack object be known at compile time (you can't simply "squeeze" another type into it at runtime). That sort of polymorphic behavior requires dynamic allocation.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by gardhr
    Your first output can't possibly be '1' - the variable 'val' is of type A..initializing it with an object of type B does nothing to the vtable. It might help to keep in mind that C++ requires that the size of a stack object be known at compile time (you can't simply "squeeze" another type into it at runtime).
    Good catch. What you are looking at is type slicing: only the base class A subobject of the temporary B object is copied to initialise val, which is an A object.

    Quote Originally Posted by gardhr
    That sort of polymorphic behavior requires dynamic allocation.
    No, polymorphic behaviour in C++ requires the use of pointers or references, not dynamic allocation, though dynamic allocation is typical.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    A needs a virtual destructor, and probably protected default and copy constructors.
    Last edited by King Mir; 10-23-2011 at 12:31 PM.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  9. #9
    Registered User
    Join Date
    Jul 2011
    Posts
    22
    I'm glad you brought up the point of the vtable, but I am till a little unsure why the constructor for B did not throw an error since I tried to construct an object of a different type.

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    All I see is that you tried to do

    A a = B();

    Which would call a constructor A::A(B&) which does not exist.
    However, remember that B inherits from A; thus polymorphism applies.
    Therefore, B can be passed to a function that wants an A&.
    And what do you know - there is one: the copy constructor for A.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Polymorphism
    By Eman in forum C++ Programming
    Replies: 4
    Last Post: 10-31-2010, 06:51 AM
  2. Polymorphism Help
    By forseti42 in forum C++ Programming
    Replies: 22
    Last Post: 05-07-2008, 02:12 PM
  3. Polymorphism
    By GiN0 in forum C++ Programming
    Replies: 1
    Last Post: 03-23-2007, 06:18 PM
  4. what is polymorphism and how can I use it
    By Tonyukuk in forum C++ Programming
    Replies: 3
    Last Post: 01-20-2003, 04:23 PM
  5. polymorphism
    By Unregistered in forum C++ Programming
    Replies: 10
    Last Post: 12-19-2001, 12:13 AM

Tags for this Thread