Thread: Virtual functions problem

  1. #1
    Just because ygfperson's Avatar
    Join Date
    Jan 2002
    Posts
    2,490

    Virtual functions problem

    I'm writing an equation parser, and taking quite a bit of time to do it. Basically, there are three base classes: Expression, Term, Factor. Expression has the ability to contain any number of Term's and Term has the ability to contain any number of Factor's (through vector classes).

    To simplify future matters, I decided to derive a few classes from base class Factor: Numeral, Variable, Function, Factor_Expression
    class Numeral also derives two other classes from it: Integer, Float

    I want to write a display() function which would take as a parameter an ostream& and output some useful data to it. For instance:
    Code:
    int Integer::display(ostream& out) {
      out << value;  //value is an int
    
    }
    To simplify things again, I decided to put a display() function in Expression, and in Term. ie:
    Code:
    class Term {
    //stuff
      vector<Factor> factors;
      int display(ostream&);
    //other stuff
    }
    class Expression {
    //stuff
      vector<Term> terms;
      int display(ostream&);
    //other stuff
    }
    The display functions listed here would just call the display functions of each term or factor in the array.

    My question is how do I make it so that whenever display() is called for each vector<Factor>, it calls the function of the most derived class? I've declared every display function virtual, but it always calls the Factor base class's function instead.

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    This should clear things up:
    Code:
    class Base
    {
    public:
        virtual void display() {cout << "Base" << endl;}
    };
    
    class DerivedA : public Base
    {
    public:
        virtual void display() {cout << "DerivedA" << endl;}
    };
    
    class DerivedB : public Base
    {
    public:
        virtual void display() {cout << "DerivedB" << endl;}
    };
    
    
    int main(void)
    {
        vector<Base> v1;
        vector<Base*> v2;
        int n;
    
        v1.push_back(*(new DerivedB()));
        v1.push_back(*(new DerivedB()));
        v1.push_back(*(new DerivedA()));
        v1.push_back(*(new Base()));
    
        cout << "instance vector:" << endl;
        for (n = 0; n < v1.size(); n++)
            v1[n].display();
    
    
        v2.push_back(new DerivedB());
        v2.push_back(new DerivedB());
        v2.push_back(new DerivedA());
        v2.push_back(new Base());
    
        cout << endl << "pointer vector:" << endl;
        for (n = 0; n < v2.size(); n++)
            v2[n]->display();
    
        return 0;
    }
    [EDIT]
    Calls to "delete" omitted for brevity

    gg
    Last edited by Codeplug; 04-05-2003 at 08:56 AM.

  3. #3
    Skunkmeister Stoned_Coder's Avatar
    Join Date
    Aug 2001
    Posts
    2,572
    zip up your project and ill take a look at it.
    Free the weed!! Class B to class C is not good enough!!
    And the FAQ is here :- http://faq.cprogramming.com/cgi-bin/smartfaq.cgi

  4. #4
    Just because ygfperson's Avatar
    Join Date
    Jan 2002
    Posts
    2,490
    There's not really much finished yet to the project, it's in its beginning stages. There are two files: a cpp file and a header file, and they're both attached in the zip below.

    Here's my response for the program you posted:
    instance vector:
    Base
    Base
    Base
    Base

    pointer vector:
    DerivedB
    DerivedB
    DerivedA
    Base
    Is there any way to make the instance vector use the most derived function, like the pointer vector does?

  5. #5
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    No, have to use a pointer. Is there a reason why you want to use instances?

    gg

  6. #6
    Just because ygfperson's Avatar
    Join Date
    Jan 2002
    Posts
    2,490
    Just to save on the hassle of memory management with new and delete.

    Thanks for the info.

  7. #7
    Skunkmeister Stoned_Coder's Avatar
    Join Date
    Aug 2001
    Posts
    2,572
    ygf what codeplug tried to show you is that if you use objects rather than pointers to objects you in fact slice off the derivedness of the object as so as it is now a base and not a derived it has full base behaviour. Thats why base functions get called. This is one of the most important concepts of polymorphic OOP. Read all you can about slicing. Understand why and how slicing occurs. You virtually never need to slice an object deliberately. And to do so as a mistake leads to obvious problems.
    Free the weed!! Class B to class C is not good enough!!
    And the FAQ is here :- http://faq.cprogramming.com/cgi-bin/smartfaq.cgi

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 7
    Last Post: 11-17-2008, 01:00 PM
  2. A question related to strcmp
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 07-07-2007, 02:51 PM
  3. Program with Shapes using Virtual Functions
    By goron350 in forum C++ Programming
    Replies: 12
    Last Post: 07-17-2005, 01:42 PM
  4. Virtual Functions
    By guda in forum C++ Programming
    Replies: 3
    Last Post: 11-16-2004, 04:13 PM
  5. Exporting Object Hierarchies from a DLL
    By andy668 in forum C++ Programming
    Replies: 0
    Last Post: 10-20-2001, 01:26 PM