Thread: Problems with polymorphism

  1. #1
    Registered User
    Join Date
    Dec 2002
    Posts
    56

    Problems with polymorphism

    The Math thread got me thinking about implementing a set of classes to model different kinds of functions. What I have now is a base class called "Function" and derived classes "Constant" (simple numbers) and "Monomial" (a number times "x" to a power).

    I'm having problems with the polymorphism aspect of it. I want to declare certain virtual functions (for example, taking a derivative) in the Function class that I will define in every derived class so that I can call them on any object of tyep Function, but I can't define them in the base class because it will be different for each derived class. So I made them pure virtual. There are other functions, however, (like "solve"), which I want to define in Function because they will be the same for all derived classes as well. Is it not allowed to have both pure virtual functions and normal, defined functions in a base class? I get an error with Borland 5.5 saying "Class 'Function' may not contain pure functions" on the line where I declare the pure virtual function.

    This is what I would like to be able to do, in the end:
    vector<Function> someFuncs; // (not sure if this would have to be a vector of pointers, but that shouldn't be related to the problem I'm having yet)
    someFuncs.push_back( Monomial(3,5) );
    someFuncs.push_back( Constant(12.2) );
    someFuncs.push_back( Exponential(3) ); // although I haven't even defined this class yet
    // :
    // :
    // :
    for( vector<Function>::iterator i = someFuns.begin(); i <= someFuncs.end(); i++ ) {
    std::cout << i.derivative() << "\n;
    // The above line would call different versions of the function "derivative"
    std::cout << i.solve(5,0);
    // This one, however, would always call the same code
    }
    The other problem (which is actually worse because I haven't thought of a workaround) is related to these. I have defined these pure virtual functions like derivative to return Function objects. In reality, they will always be some subclass of Function like Monomial. The compiler complains that it can't instantiate an object of type Function. I understand why, but how else can I define it? More importantly, when I call derivative() on a Monomial, it will return another Monomial, but I can't use it as such because the compiler thinks it's a Function. Do I have to use pointers to fix these problems? What about references? I tried ref's but I can't return a ref to a local object, and with pointers it doesn't make much sense to create the objects on the stack and expect the user to delete them.

    Any help would be appreciated...

  2. #2
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    There are a couple problems you are having. The first deals with the fact that you are creating a vector of 'Function' objects, which are ADTs. When you create the vector, it tries to create copies of the specified type, which it cannot do since it is an ADT. It can, however, create pointers to ADTs since you never create the ADTs themselves.

    The second problem you are running into is that you are trying to cast between the types of objects, not pointers to the types of objects. You can cast from a pointer to the base type to a pointer of the derived type, but cannot convert the objects themselves since, regardless of relation, they are distinct objects.

    Here is some code that might help make this clearer:

    Code:
    #include <cstdlib>
    #include <iostream>
    #include <vector>
    
    class base
    {
    public:
        virtual void func() = 0;
    };
    
    class derived1 : public base
    {
    public:
        virtual void func()
        {
            std::cout << "The answer is 3." << std::endl;
        }
    };
    
    class derived2 : public base
    {
    public:
        virtual void func()
        {
            std::cout << "The answer is 42." << std::endl;
        }
    };
    
    int main(int argc, char **argv)
    {
        std::vector<base*> vec(6);
        std::vector<base*>::iterator it;
        int k = 0;
    
        for(it = vec.begin(); it != vec.end(); ++it, ++k)
        {
            if(k % 2 == 0)
                (*it) = new derived1;
            else
                (*it) = new derived2;
        }
    
        for(it = vec.begin(); it != vec.end(); ++it)
            (*it)->func();
    
        std::system("pause");
    
        return 0;
    }
    Cheers
    The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.

  3. #3
    Registered User
    Join Date
    Dec 2002
    Posts
    56
    Thanks for the help. That's what I believed was supposed to work, but the problems were elsewhere. (Actually, I hadn't gotten to the part about even writing that code with the vector yet.) To get it to work, I changed the functions that return a Function to return a Function*. I didn't like this idea because I didn't see why it was necessary to use dynamic allocation, but I solved the destruction problem by storing the value in the class, and having its destructor delete it. Thanks again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Polymorphism - "pointers" or "references"?
    By Petike in forum C++ Programming
    Replies: 10
    Last Post: 06-04-2009, 05:06 PM
  2. No clue how to make a code to solve problems!
    By ctnzn in forum C Programming
    Replies: 8
    Last Post: 10-16-2008, 02:59 AM
  3. C Pointers Problems
    By mhelal in forum C Programming
    Replies: 8
    Last Post: 01-10-2007, 06:35 AM
  4. String Manipulation problems -_-
    By Astra in forum C Programming
    Replies: 5
    Last Post: 12-13-2006, 05:48 PM
  5. contest problems on my site
    By DavidP in forum Contests Board
    Replies: 4
    Last Post: 01-10-2004, 09:19 PM