Class design problem

This is a discussion on Class design problem within the C++ Programming forums, part of the General Programming Boards category; Hallo, I am working on a program where I need to create a lot of different classes of almost the ...

  1. #1
    Registered User
    Join Date
    Oct 2006
    Location
    UK/Norway
    Posts
    485

    Class design problem

    Hallo,

    I am working on a program where I need to create a lot of different classes of almost the same type. But I am not sure how I should design the program so that it is easy to add a new class.

    Here are the restrictions which makes it harder.
    The classes has to work with the rest of the program (which is not written by me, and can not be change by me).

    This is the base class which I can derive from in order to create a new class
    Code:
    class Man 
    {
    public:
    	virtual void gatherInfo( /* a variable map */ ) = 0;
    	virtual void doWork() = 0;
    }
    Right now I am doing this when I create new classes:
    Code:
    class IronWorker : public Man
    {
    	public:
    		void gatherInfo( /* a variable map */ );
    		void doWork();
    
    	public:
    		std::string m_name;
    		int m_age;
    		std::string m_workplace;
    
    		std::string m_factoryName;
    		std::string m_ironType;
    }
    
    class GarderWorker : public Man
    {
    	public:
    		void gatherInfo( /* a variable map */ );
    		void doWork();
    
    	public:
    		std::string m_name;
    		int m_age;
    		std::string m_workplace;
    
    		std::string m_houseAdress;
    		std::string m_floworNames[50];
    		int m_kgDirtUsed;
    }
    When the program starts it goes into the gatherInfo() function of everyman and take the information in that map and stores it in the member variables. There are several variables that will be the same for every derived class (like name and age) but as of now I have to duplicate that code in every worker.

    What I would like is to create classes more like this:
    Code:
    // A "new" base class
    class Worker : public Man
    {
    public:
    	void gatherInfo( /* a variable map */ );
    	void doWork();
    
    public:
    	std::string m_name;
    	int m_age;
    	std::string m_workplace;
    };
    
    class IronWorker : public baseWorker
    {
    	public:
    		void gatherInfo( /* a variable map */ );
    		void doWork();
    
    	public:
    		std::string m_factoryName;
    		std::string m_ironType;
    }
    
    class GarderWorker : public baseWorker
    {
    	public:
    		void gatherInfo( /* a variable map */ );
    		void doWork();
    
    	public:
    		std::string m_houseAdress;
    		std::string m_floworNames[50];
    		int m_kgDirtUsed;
    }
    In the code there the base variables will be gathered by the baseWorker class. But the gatherInfo function in baseWorker would never be called as it is a pure virtual function.

    Any ideas on how to create a more user friendly way of doing this?
    (The two virtual functions are the only two function that is called by the program)

  2. #2
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    I think you wanted to type this:
    Code:
    class baseWorker : public Man
    I don't really see the problem of what you are doing.
    The only "problem" seems that you won't call baseWorker gatherInfo and doWork functions ever.
    So if you want to "fix" this just don't declare them. Do this:
    Code:
    class baseWorker : public Man
    {
    public:
    	std::string m_name;
    	int m_age;
    	std::string m_workplace;
    };
    Note that baseWoker is also an abstract class. But that is OK with you, since you won't use it. I guess this is what you wanted.

    Pure virtual functions have to be declared only once, making the class "valid" to use (not abstract anymore).

    Other than that your idea is good and I don't see anything else to add

  3. #3
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,649
    >> But the gatherInfo function in baseWorker would never be called...
    Just because it's virtual doesn't mean you can't be explicit in what you want to call. You can "chain" the virtual calls for example:
    Code:
    #include <iostream>
    using namespace std;
    
    struct base
    {
        virtual void print_topdown() = 0 {cout << " base" << endl;}
        virtual void print_bottomup() = 0 {cout << " base" << endl;}
    };//base
    
    struct derived : public base
    {
        virtual void print_topdown() 
        {
            cout << " derived" << endl;
            base::print_topdown();
        }
        
        virtual void print_bottomup() 
        {
            base::print_bottomup();
            cout << " derived" << endl;
        }
    };//derived
    
    struct further_derived : public derived
    {
        virtual void print_topdown() 
        {
            cout << " further_derived" << endl;
            derived::print_topdown();
        }
    
        virtual void print_bottomup() 
        {
            derived::print_bottomup();
            cout << " further_derived" << endl;
        }
    };//further_derived
    
    int main()
    {
        further_derived fd;
        base *b = &fd;
        cout << "Top-Down:" << endl;
        b->print_topdown();
    
        cout << "\nBottom-Up" << endl;
        b->print_bottomup();
        return 0;
    }//main
    gg

  4. #4
    Registered User
    Join Date
    Oct 2006
    Location
    UK/Norway
    Posts
    485
    Codeplug: I did not know you could do that. It solved my problem perfectly! Thank you very very much

  5. #5
    The larch
    Join Date
    May 2006
    Posts
    3,573
    That doesn't compile, at least not with GCC or Comeau.

    It appears that the implementation of pure virtual functions needs to be outside of the class:

    Code:
    struct base
    {
        virtual void print_topdown() = 0;
        virtual void print_bottomup() = 0;
    };//base
    
    void base::print_topdown()
    {
        cout << " base" << endl;
    }
    
    void base::print_bottomup()
    {
        cout << " base" << endl;
    }
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  6. #6
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,236
    Quote Originally Posted by anon View Post
    That doesn't compile, at least not with GCC or Comeau.

    It appears that the implementation of pure virtual functions needs to be outside of the class:
    Why would you implement a pure virtual? That makes it not pure.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  7. #7
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,649
    Provide a default implementation, and enforce derive'ers to make their own. Never used it myself, but it seemed appropriate for the example since each derivation builds on the previous.

    Good catch anon - MSVC blinded me

    gg

  8. #8
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Why would you implement a pure virtual? That makes it not pure.
    I think what makes it "pure" is the = 0 tagged onto the prototype. You would at least have to agree that a pure virtual destructor has to have an implementation since all base classes will have their destructor called (perhaps this is your only option to make the class abstract, since no other method is a good candidate for being pure).
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  9. #9
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,449
    Code:
    class Man 
    {
    public:
    	virtual void gatherInfo( /* a variable map */ ) = 0;
    	virtual void doWork() = 0;
    }
    Code:
    class IronWorker : public Man
    {
    	public:
    		virtual void gatherInfo( /* a variable map */ );
    		virtual void doWork();
    
    	public:
    		std::string m_name;
    		int m_age;
    		std::string m_workplace;
    
    		std::string m_factoryName;
    		std::string m_ironType;
    }
    Another note is that while the language does not enforce you to add "virtual" to function that is a inherited virtual function, it would be good practice, since anyone looking at that class would know it is indeed virtual without looking at the base class.
    Further, all your member variables are public, exposed, which makes for poor abstraction. You really need to hide them.
    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.

  10. #10
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Yeah, I wanted to mention that earlier but I forgot. Since the gatherInfo(), as you say, will get information and store them and the doWork() will do the job, probably you want all the variables private. You might want another function, like printInfo() to print the variables.

  11. #11
    Registered User
    Join Date
    Oct 2006
    Location
    UK/Norway
    Posts
    485
    In my real program they are private. The worker classes was just something that I created as an example.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  2. which design is better to wrap another class instance
    By George2 in forum C++ Programming
    Replies: 7
    Last Post: 04-13-2008, 12:27 AM
  3. singleton class problem
    By ... in forum C++ Programming
    Replies: 6
    Last Post: 12-22-2003, 05:16 PM
  4. Quaternion class problem
    By Lurker in forum C++ Programming
    Replies: 14
    Last Post: 11-18-2003, 05:01 PM
  5. static class problem.
    By Sebastiani in forum C++ Programming
    Replies: 3
    Last Post: 10-16-2002, 03:27 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21