Solved

can't create object of type "System" before it's declared

Posted on 2012-03-12
4
197 Views
Last Modified: 2012-03-29
I think maybe I need to divide my code up into headers and stuff but the C++ way of doing this seems completely wrong to me I don't see the pattern.

Maybe my mistake is something else
#include <stack>
#include <vector>
#include <string>
#include <queue>
#include <iostream>
//#include "scheduler.h"
using namespace std;

#define NUMBER_OF_PROCESSORS 8
#define MAX_JOBS 2

System system_; // this simulates system features normally outside of the scheduler


class JobRequest
/*  This represents a request to create a job it had yet to actually
 * move on to that point in it's lifecycle.. note the lack of PID
*/
{
private:
    string name_;
    int numberOfProcessors_;
    int numberOfTicks_;
public:
    JobRequest(string name, int numberOfProcessors, int numberOfTicks)
    {
       name_ = name_;
       numberOfProcessors_ = numberOfProcessors;
       numberOfTicks_ = numberOfTicks;
    }
    string getName()
    /*returns the name of the job, exmple: ls, pwd, javac*/
    {
        return name_;
    }
    int getProcessingRequirements()
    /*returns the number of processors required to run this job*/
    {
        return numberOfProcessors_;
    }
    int getTicksRequired()
    /* Returns the number of ticks this program is going to consume*/
    {
        return numberOfTicks_;
    }
};
class Processor
/* This class represents processors                 *
 * it includes a processor ID but it's not          *
 * yet important                                    *
 *                                                 */
{
private:
    int processorID_;        // This is a unique integet to tell one processor 
                             // from the next
    string type_;  //This tells what type of processor 
                                          // is attached to the object
public:
    Processor()
    {
        processorID_ = 0;
        type_ =  "GenuineMakeBelieve";
        // this is all just examples we could put all kinds of stuff
        // in here to tie this to a real processor and get statistics 
        // or even have affinity for some jobs to certian types of processors
        // but this is all make believe anyhow
    }
    int getID()
    /* This should return the processor ID*/
    {
        return processorID_;
    }
    string getType()
    /*This should return a string identifying the sort of processor
     */
    {
        return type_;
    }
    
};
class System
/* This class represents the system it's for storing the state of anything
 * that doesn't clearly belong in some other class
 * right now it only stores the free processor pool and the current next 
 * process ID
 */
{
private:

    int nextPid;
    vector<Processor> freePool_;
public:
    System()
    {   
        //freePool_ = new vector<Processor>;
        // I shouldn't need this because these System objects will stick around
        // for the duration of the program's execution anyhow.  like "new System"
        nextPid = 0;
        
    }
    int getPID()   /// static int getPID() ???
    /*This allocates and returns the next available process ID*/
    {
        return ++nextPid; 
    }
    Processor getProcessor()
    /* This method gets a free processor from the system*/
    {
        Processor r = freePool_.back();
        freePool_.pop_back();
        return r;
    }
    void takeProcessor(Processor processor)
    /* This method gives the processor back to the system*/
    {
        freePool_.push_back(processor);
    }
   
};



class Job;

        bool operator>= (Job &job1, Job &job2);
        bool operator<= (Job &job1, Job &job2);
        bool operator== (Job &job1, Job &job2);
        bool operator!= (Job &job1, Job &job2);
        ostream &operator<< (ostream& out, const Job &job);

class Job
/* The job class represents an actual job with a name
 * a stack of captured processors a list of ticks and a PID for the job*/
{
    
   /*
    friend bool operator>= (Job &job1, Job &job2);
    friend bool operator<= (Job &job1, Job &job2);
    friend bool operator== (Job &job1, Job &job2);
    friend bool operator!= (Job &job1, Job &job2);
    friend ostream &operator<<(ostream& out,const Job& job); */
    
private:
    vector<Processor> captiveProcessors_;
    string name_;
    int PID_;
    int ticksRemaining_;
public:
    Job(string name, int processors, int ticks)
    {
        name_ = name;
        ticksRemaining_ = ticks;
        PID_ = system_.getPID();
    }
    void takeProcessor(Processor processor)
    /*This takes a processor and makes it captive*/
    {
        captiveProcessors_.push_back(processor);
    }
    int tick()
    /*decrement the ticks and return ticks remaining*/
    {
        return --ticksRemaining_;
    }
    
    
    friend bool operator>= (Job &job1, Job &job2)
    {
        return job1.ticksRemaining_ >= job2.ticksRemaining_;
    }
    friend bool operator<= (Job &job1, Job &job2)
    {
        return job1.ticksRemaining_ <= job2.ticksRemaining_;
    }
    friend bool operator== (Job &job1, Job &job2)
    {
        return job1.ticksRemaining_ == job2.ticksRemaining_;
    }
    friend bool operator!= (Job &job1, Job &job2)
    {
        return job1.ticksRemaining_ != job2.ticksRemaining_;
    }
    friend ostream &operator<<(ostream& out,const Job& job)
    {
        out <<job.name_ << "\t" job.PID_ << "\t" + job.ticksRemaining_ << "\t\n";
        return out;
    }
};

class Scheduler
/* This class represents a scheduler object
 What should happen here is the user should be able to submit
 * a job request (sendjobrequest). it should get enqueud in a regular queue and
 *  at each tick it will 
 * convert those requests into 
 */
{ 
private:
    vector<Job> runQueue_;  //  This is the queue that running jobs sit in
    vector<Job> waitQueue_; //  This is the queue that not running jobs sit in
    void tickRunQueue()
    /*private method to manipulate the runQueue*/
    {
        for (int i=0; i<=runQueue_.size();i++)
        {
           if (0 >= runQueue_.at(i).tick())
           /* if there are no ticks left anyhow then free the memory and remove 
            the pointer from the Queue*/
           {
               //delete(runQueue_.back());
               runQueue_.pop_back();
           }
           
           cout << runQueue_.at(i);
        }
    }
    void tickWaitQueue()
    /* private method to move a */
    {
        runQueue_.push_back(waitQueue_.back());
        waitQueue_.pop_back();
    }
   
public:
    Scheduler()
    {
        //runQueue_ = new vector<Job>();
        //waitQueue_ = new vector<Job>();
    }
    processJobRequest(JobRequest jobRequest)
    /* This converts a job request into an actual job
       This is where jobRequests go to die*/
    {
        waitQueue_.push_back(new Job(jobRequest.getName(), jobRequest.getProcessingRequirements(),jobRequest.getTicksRequired()));
        //delete(jobRequest);
    }
    tick()
    {
        // I would make a queue that you can put new submissions to and a threaded
        // shell.. but I looked at pthreads,, no that's not going to happen, and 
        // honestly I don't know any other sensible way to allow users to submit
        // a job during any tick.. but here are some comments
        // if (submissionqueue) {pop the thing off the queue and processoJobRequest()
        // good enough  
        // I take that back maybe I'll use kbhit() to get some text input if I have time
        // forget it I don't even have the curses libraries installed.. no interactive shell
    
        // if queue is not empty and enough processors are available then pop
        // a job off and give it processors     
        
    }
    
};






int main()
{
    // System objects, scheduler and system get created here
    // Processors get created too
 
    //system_ = new System();
    Scheduler scheduler; // = new Scheduler();
    
    /*make the processors*/
    for (int i = 0; i < NUMBER_OF_PROCESSORS; i++)
    {
        system_.takeProcessor(new Processor());
    }
    
    scheduler.processJobRequest( JobRequest("nethack", 2, 4));
    scheduler.processJobRequest( JobRequest("gcc", 4, 2));
    scheduler.processJobRequest( JobRequest("pwd", 7, 3));
    scheduler.processJobRequest( JobRequest("javac", 3, 8));
    scheduler.processJobRequest( JobRequest("clear", 3, 3));
    scheduler.processJobRequest( JobRequest("fortune", 1, 1));
            
    
    scheduler.processJobRequest( JobRequest("nethack", 2, 4));
    scheduler.processJobRequest( JobRequest("gcc", 4, 2));
    scheduler.processJobRequest( JobRequest("pwd", 7, 3));
    scheduler.processJobRequest( JobRequest("javac", 3, 8));
    scheduler.processJobRequest( JobRequest("clear", 3, 3));
    scheduler.processJobRequest( JobRequest("fortune", 1, 1));
            
    
    scheduler.processJobRequest( JobRequest("nethack", 2, 4));
    scheduler.processJobRequest( JobRequest("gcc", 4, 2));
    scheduler.processJobRequest( JobRequest("pwd", 7, 3));
    scheduler.processJobRequest( JobRequest("javac", 3, 8));
    scheduler.processJobRequest( JobRequest("clear", 3, 3));
    scheduler.processJobRequest( JobRequest("fortune", 1, 1));
            
    
    scheduler.processJobRequest( JobRequest("nethack", 2, 4));
    scheduler.processJobRequest( JobRequest("gcc", 4, 2));
    scheduler.processJobRequest( JobRequest("pwd", 7, 3));
    scheduler.processJobRequest( JobRequest("javac", 3, 8));
    scheduler.processJobRequest( JobRequest("clear", 3, 3));
    scheduler.processJobRequest( JobRequest("fortune", 1, 1));
    
    while(1)
    {
        scheduler.tick();
    }
            
    
}

Open in new window

0
Comment
Question by:GPicasso
  • 2
4 Comments
 
LVL 86

Expert Comment

by:jkr
Comment Utility
Well, you only can do that via a foward declaration when you are defining it as a pointer - yet the problem remains that you cannot use any of its members, since the compiler would still regard it as an 'incomplete type'. Move thedeclaration of the instance right after the definition of the class and try to keep it 'topmost'. Also, why do you keep moving the global binary operators back into the class, since that simply won't work?

This here will compile:

#include <stack>
#include <vector>
#include <string>
#include <queue>
#include <iostream>
//#include "scheduler.h"
using namespace std;

#define NUMBER_OF_PROCESSORS 8
#define MAX_JOBS 2



class JobRequest
/*  This represents a request to create a job it had yet to actually
 * move on to that point in it's lifecycle.. note the lack of PID
*/
{
private:
    string name_;
    int numberOfProcessors_;
    int numberOfTicks_;
public:
    JobRequest(string name, int numberOfProcessors, int numberOfTicks)
    {
       name_ = name_;
       numberOfProcessors_ = numberOfProcessors;
       numberOfTicks_ = numberOfTicks;
    }
    string getName()
    /*returns the name of the job, exmple: ls, pwd, javac*/
    {
        return name_;
    }
    int getProcessingRequirements()
    /*returns the number of processors required to run this job*/
    {
        return numberOfProcessors_;
    }
    int getTicksRequired()
    /* Returns the number of ticks this program is going to consume*/
    {
        return numberOfTicks_;
    }
};
class Processor
/* This class represents processors                 *
 * it includes a processor ID but it's not          *
 * yet important                                    *
 *                                                 */
{
private:
    int processorID_;        // This is a unique integet to tell one processor 
                             // from the next
    string type_;  //This tells what type of processor 
                                          // is attached to the object
public:
    Processor()
    {
        processorID_ = 0;
        type_ =  "GenuineMakeBelieve";
        // this is all just examples we could put all kinds of stuff
        // in here to tie this to a real processor and get statistics 
        // or even have affinity for some jobs to certian types of processors
        // but this is all make believe anyhow
    }
    int getID()
    /* This should return the processor ID*/
    {
        return processorID_;
    }
    string getType()
    /*This should return a string identifying the sort of processor
     */
    {
        return type_;
    }
    
};
class System
/* This class represents the system it's for storing the state of anything
 * that doesn't clearly belong in some other class
 * right now it only stores the free processor pool and the current next 
 * process ID
 */
{
private:

    int nextPid;
    vector<Processor> freePool_;
public:
    System()
    {   
        //freePool_ = new vector<Processor>;
        // I shouldn't need this because these System objects will stick around
        // for the duration of the program's execution anyhow.  like "new System"
        nextPid = 0;
        
    }
    int getPID()   /// static int getPID() ???
    /*This allocates and returns the next available process ID*/
    {
        return ++nextPid; 
    }
    Processor getProcessor()
    /* This method gets a free processor from the system*/
    {
        Processor r = freePool_.back();
        freePool_.pop_back();
        return r;
    }
    void takeProcessor(Processor processor)
    /* This method gives the processor back to the system*/
    {
        freePool_.push_back(processor);
    }
   
};

System system_; // this simulates system features normally outside of the scheduler


class Job;

        bool operator>= (Job &job1, Job &job2);
        bool operator<= (Job &job1, Job &job2);
        bool operator== (Job &job1, Job &job2);
        bool operator!= (Job &job1, Job &job2);
        ostream &operator<< (ostream& out, const Job &job);

class Job
/* The job class represents an actual job with a name
 * a stack of captured processors a list of ticks and a PID for the job*/
{
    
   
    friend bool operator>= (Job &job1, Job &job2);
    friend bool operator<= (Job &job1, Job &job2);
    friend bool operator== (Job &job1, Job &job2);
    friend bool operator!= (Job &job1, Job &job2);
    friend ostream &operator<<(ostream& out,const Job& job);
    
private:
    vector<Processor> captiveProcessors_;
    string name_;
    int PID_;
    int ticksRemaining_;
public:
    Job(string name, int processors, int ticks)
    {
        name_ = name;
        ticksRemaining_ = ticks;
        PID_ = system_.getPID();
    }
    void takeProcessor(Processor processor)
    /*This takes a processor and makes it captive*/
    {
        captiveProcessors_.push_back(processor);
    }
    int tick()
    /*decrement the ticks and return ticks remaining*/
    {
        return --ticksRemaining_;
    }
    
    
};

    bool operator>= (Job &job1, Job &job2)
    {
        return job1.ticksRemaining_ >= job2.ticksRemaining_;
    }
    bool operator<= (Job &job1, Job &job2)
    {
        return job1.ticksRemaining_ <= job2.ticksRemaining_;
    }
    bool operator== (Job &job1, Job &job2)
    {
        return job1.ticksRemaining_ == job2.ticksRemaining_;
    }
    bool operator!= (Job &job1, Job &job2)
    {
        return job1.ticksRemaining_ != job2.ticksRemaining_;
    }
    ostream &operator<<(ostream& out,const Job& job)
    {
        out <<job.name_ << "\t" << job.PID_ << "\t" << job.ticksRemaining_ << "\t\n"; // no +, just <<
        return out;
    }


class Scheduler
/* This class represents a scheduler object
 What should happen here is the user should be able to submit
 * a job request (sendjobrequest). it should get enqueud in a regular queue and
 *  at each tick it will 
 * convert those requests into 
 */
{ 
private:
    vector<Job> runQueue_;  //  This is the queue that running jobs sit in
    vector<Job> waitQueue_; //  This is the queue that not running jobs sit in
    void tickRunQueue()
    /*private method to manipulate the runQueue*/
    {
        for (int i=0; i<=runQueue_.size();i++)
        {
           if (0 >= runQueue_.at(i).tick())
           /* if there are no ticks left anyhow then free the memory and remove 
            the pointer from the Queue*/
           {
               //delete(runQueue_.back());
               runQueue_.pop_back();
           }
           
           cout << runQueue_.at(i);
        }
    }
    void tickWaitQueue()
    /* private method to move a */
    {
        runQueue_.push_back(waitQueue_.back());
        waitQueue_.pop_back();
    }
   
public:
    Scheduler()
    {
        //runQueue_ = new vector<Job>();
        //waitQueue_ = new vector<Job>();
    }
    void processJobRequest(JobRequest jobRequest) // return type required
    /* This converts a job request into an actual job
       This is where jobRequests go to die*/
    {
        // again - DON'T use 'new' unless you are dealing with pointers
        waitQueue_.push_back(Job(jobRequest.getName(), jobRequest.getProcessingRequirements(),jobRequest.getTicksRequired()));
        //delete(jobRequest);
    }
    void tick()
    {
        // I would make a queue that you can put new submissions to and a threaded
        // shell.. but I looked at pthreads,, no that's not going to happen, and 
        // honestly I don't know any other sensible way to allow users to submit
        // a job during any tick.. but here are some comments
        // if (submissionqueue) {pop the thing off the queue and processoJobRequest()
        // good enough  
        // I take that back maybe I'll use kbhit() to get some text input if I have time
        // forget it I don't even have the curses libraries installed.. no interactive shell
    
        // if queue is not empty and enough processors are available then pop
        // a job off and give it processors     
        
    }
    
};






int main()
{
    // System objects, scheduler and system get created here
    // Processors get created too
 
    //system_ = new System();
    Scheduler scheduler; // = new Scheduler();
    
    /*make the processors*/
    for (int i = 0; i < NUMBER_OF_PROCESSORS; i++)
    {
        system_.takeProcessor(Processor()); // no pointers involved, no 'new'
    }
    
    scheduler.processJobRequest( JobRequest("nethack", 2, 4));
    scheduler.processJobRequest( JobRequest("gcc", 4, 2));
    scheduler.processJobRequest( JobRequest("pwd", 7, 3));
    scheduler.processJobRequest( JobRequest("javac", 3, 8));
    scheduler.processJobRequest( JobRequest("clear", 3, 3));
    scheduler.processJobRequest( JobRequest("fortune", 1, 1));
            
    
    scheduler.processJobRequest( JobRequest("nethack", 2, 4));
    scheduler.processJobRequest( JobRequest("gcc", 4, 2));
    scheduler.processJobRequest( JobRequest("pwd", 7, 3));
    scheduler.processJobRequest( JobRequest("javac", 3, 8));
    scheduler.processJobRequest( JobRequest("clear", 3, 3));
    scheduler.processJobRequest( JobRequest("fortune", 1, 1));
            
    
    scheduler.processJobRequest( JobRequest("nethack", 2, 4));
    scheduler.processJobRequest( JobRequest("gcc", 4, 2));
    scheduler.processJobRequest( JobRequest("pwd", 7, 3));
    scheduler.processJobRequest( JobRequest("javac", 3, 8));
    scheduler.processJobRequest( JobRequest("clear", 3, 3));
    scheduler.processJobRequest( JobRequest("fortune", 1, 1));
            
    
    scheduler.processJobRequest( JobRequest("nethack", 2, 4));
    scheduler.processJobRequest( JobRequest("gcc", 4, 2));
    scheduler.processJobRequest( JobRequest("pwd", 7, 3));
    scheduler.processJobRequest( JobRequest("javac", 3, 8));
    scheduler.processJobRequest( JobRequest("clear", 3, 3));
    scheduler.processJobRequest( JobRequest("fortune", 1, 1));
    
    while(1)
    {
        scheduler.tick();
    }
            
    
}
                                  

Open in new window

0
 
LVL 32

Accepted Solution

by:
sarabande earned 400 total points
Comment Utility
you told rightly that you should use header files. i'll show you how to use one header file for each class (it also would be ok to put all class definitions to one header but has different issues then).

// jobrequest.h
#ifndef JOBREQUEST_INCLUDED
#define JOBREQUEST_INCLUDED

#include <string>

class JobRequest
/*  This represents a request to create a job it had yet to actually
 * move on to that point in it's lifecycle.. note the lack of PID
*/
{
private:
    std::string name_;
    int numberOfProcessors_;
    int numberOfTicks_;
public:
    JobRequest(const std::string & name, int numberOfProcessors, int numberOfTicks)
    {
       name_ = name;
       numberOfProcessors_ = numberOfProcessors;
       numberOfTicks_ = numberOfTicks;
    }
    std::string getName()
    /*returns the name of the job, exmple: ls, pwd, javac*/
    {
        return name_;
    }
    int getProcessingRequirements()
    /*returns the number of processors required to run this job*/
    {
        return numberOfProcessors_;
    }
    int getTicksRequired()
    /* Returns the number of ticks this program is going to consume*/
    {
        return numberOfTicks_;
    }
};

#endif   // JOBREQUEST_INCLUDED

Open in new window


the above is header file for class JobRequest. beside of the comment it begins with a so-called header protection which should prevent the header from being included twice. the header protection checks whether the macro (== name for preprocessor symbol)  JOBREQUEST_INCLUDED already exists and if not the macro will be defined (it has no value but exists for the preprocessor next time). such duplicate includes could happen cause we would add #include "jobrequest.h" to each source file (.h or .cpp) which needs access to class JobRequest, so the including firstly could happen by including another header and secondly when including the header in the cpp file.  

the next statement includes <string> what is the headerfile for std::string class. it is a rule that headerfiles need to include all other headerfiles where they were dependent of. the class JobRequest needs std::string hence the include statement. however, the header doesn't contain a using clause which would allow to omit the std:: prefix. that is cause header files should made such they could be used if you decide to try a 'string' class of another namespace in your cpp. if a header would contain a 'using namespace std;' clause, this would not be possible. but because of that, i needed to add the std:: wherever the 'string' class was used in the header. the rest of the class didn't change beside of two things: i changed the 'string' argument of the constructor to 'const std::string &' what doesn't require a copy of the string and is the normal way to pass string input variables. and then i corrected a bug cause you had 'name_ = name_;' in your implementation what would have not taken the input 'name'.

note, using suffix _ for member variables is widely done but i personally don't like it cause it is not well readable and may have lead to the buggy statement.

the header for class Processor could be made same way.

// mysystem.h
#ifndef MYSYSTEM_INCLUDED
#define MYSYSTEM_INCLUDED

#include "processor.h"
#include <vector>

class System
/* This class represents the system it's for storing the state of anything
 * that doesn't clearly belong in some other class
 * right now it only stores the free processor pool and the current next 
 * process ID
 */
{
private:

    static int nextPid;
    std::vector<Processor> freePool_;
public:
    System()
   }
    static int getPID() 
    /*This allocates and returns the next available process ID*/
    {
        return ++nextPid; 
    }
    Processor getProcessor()
    /* This method gets a free processor from the system*/
    {
        if (freePool_.empty())
             return Processor();
        Processor r = freePool_.back();
        freePool_.pop_back();
        return r;
    }
    void takeProcessor(Processor processor)
    /* This method gives the processor back to the system*/
    {
        freePool_.push_back(processor);
    }
   
};
#endif // MYSYSTEM_INCLUDED

// system.cpp  needed for initialization of static member
#include "mysystem.h"

// static initialization
int System::nextPid = 0;

Open in new window


note, i used mysystem.h for filename cause system.h already exists in the c runtime. unfortunately the name 'system' is widely used in header files and i personally wouldn't use it as name for my own functions or classes.

the name for header protection macro could be chosen freely but it needs to be unique. so i would recommend to always deduce it from filename which should be unique as well.

we need to include the processor.h cause class System uses class Processor in a vector container. we don't need to include <string> but <vector> and again we do not have a using clause.

the nextpid must be static cause it should be unique for the class and not only for an instance of class System. same applies for member function getPID() which needs to increment the static integer and therefore could be static as well (static member functions can access static data members) what has the advantage that you don't need a System object to call the function but you could do like

int nextpid = System::getPID();

Open in new window


not an alternative for using static int nextpid member in class System would be

class System
{
     ...
     static int getNextPid() { static int nextpid = 0; return ++nextpid; }

Open in new window


that has one valuable advantage: you don't need an initialization of the static member System::nextPid as you would need now cause the initialization happens with first call. therefore you could avoid the system.cpp file where i put the static initialization into (putting the static initialization into your main cpp is also possible but not a stringent design).

the last change i made to implementation of class System is to handle the case where the processor pool was empty. std::vector would throw an exception when you use back() for an empty array, so you should handle that somehow (of course you also could handle the exception or add your own exception handling).

class  Job and Scheduler do not add more difficulties, so you should be able to create headers yourself. one point, i would omit the friend comparision operator functions and use member operators instead:

....
#include <iostream> 

class Job
{
     ....
public:
    bool operator>= (const Job &job2) const
    {
        return ticksRemaining_ >= job2.ticksRemaining_;
    }
    bool operator<= (const Job &job2) const
    {
        return ticksRemaining_ <= job2.ticksRemaining_;
    }
    bool operator==  (const Job &job2) const
    {
        return ticksRemaining_ == job2.ticksRemaining_;
    }
    bool operator!= const Job &job2) const
    {
        return ticksRemaining_ != job2.ticksRemaining_;
    }
    friend ostream &operator<<(std::ostream& out,const Job& job)
    {
        // note i fixed a bug in that statement
        out <<job.name_ << "\t" << job.PID_ << "\t" + job.ticksRemaining_ << std::endl;
        return out;
    }

Open in new window


you see the only 'friend' needed is the operator<< cause it uses class std::ostream while the comparision functions only refer to class Job and are not enhancements of a foreign class.

most compilers would accept inline implementation of friend functions as outlined above. in any case you could omit the forward declaration of friend functions cause it is done in the class header.

if you made all headers your final main cpp would look like



#include "jobrequest.h"
#include "processor.h"
#include "mysystem.h"
#include "job.h"
#include "scheduler.h"

int main()
{
    // System objects, scheduler and system get created here
    // Processors get created too
 
    System mysystem;
    Scheduler scheduler; ;
    
    /*make the processors*/
    for (int i = 0; i < NUMBER_OF_PROCESSORS; i++)
    {
        mysystem.takeProcessor(Processor()); // no pointers involved, no 'new'
    }
    
    scheduler.processJobRequest( JobRequest("nethack", 2, 4));
    scheduler.processJobRequest( JobRequest("gcc", 4, 2));
    scheduler.processJobRequest( JobRequest("pwd", 7, 3));
    scheduler.processJobRequest( JobRequest("javac", 3, 8));
    scheduler.processJobRequest( JobRequest("clear", 3, 3));
    scheduler.processJobRequest( JobRequest("fortune", 1, 1));
            
    
    scheduler.processJobRequest( JobRequest("nethack", 2, 4));
    scheduler.processJobRequest( JobRequest("gcc", 4, 2));
    scheduler.processJobRequest( JobRequest("pwd", 7, 3));
    scheduler.processJobRequest( JobRequest("javac", 3, 8));
    scheduler.processJobRequest( JobRequest("clear", 3, 3));
    scheduler.processJobRequest( JobRequest("fortune", 1, 1));
            
    
    scheduler.processJobRequest( JobRequest("nethack", 2, 4));
    scheduler.processJobRequest( JobRequest("gcc", 4, 2));
    scheduler.processJobRequest( JobRequest("pwd", 7, 3));
    scheduler.processJobRequest( JobRequest("javac", 3, 8));
    scheduler.processJobRequest( JobRequest("clear", 3, 3));
    scheduler.processJobRequest( JobRequest("fortune", 1, 1));
            
    
    scheduler.processJobRequest( JobRequest("nethack", 2, 4));
    scheduler.processJobRequest( JobRequest("gcc", 4, 2));
    scheduler.processJobRequest( JobRequest("pwd", 7, 3));
    scheduler.processJobRequest( JobRequest("javac", 3, 8));
    scheduler.processJobRequest( JobRequest("clear", 3, 3));
    scheduler.processJobRequest( JobRequest("fortune", 1, 1));
    
    while(1)
    {
        scheduler.tick();
    }
    return 0;
}

Open in new window


note, i didn't use global variable system_ but local variable mysystem. the only case where you used system_ was in Job::Job constructor to get the next pid. as told, by making the member function to get the pid a static member function, you no longer need the global system_ object but simply could call System::getPID (or System::getNextPid).

Sara
0
 
LVL 22

Expert Comment

by:ambience
Comment Utility
Hmm .. I dont think anyone has suggested this so far, so - just use a local variable and the rest is OK.

    //system_ = new System();
    System system_;
    Scheduler scheduler; // = new Scheduler();

>> the C++ way of doing this seems completely wrong to me I don't see the pattern.

Maybe, but thats not how Cipher sees the matrix
0
 
LVL 22

Assisted Solution

by:ambience
ambience earned 100 total points
Comment Utility
Oh ok, I didnt notice the dependency that Job has on the global variable system_ - and this is a design anti-pattern.

I would suggest that you change the interface of Job

    Job(string name, int processors, int ticks, int assignedSystemId)
    {
        name_ = name;
        ticksRemaining_ = ticks;
        PID_ = assignedSystemId;
    }

Also the Scheduler changes

class Scheduler
{
   System& _system;
...
   Scheduler(System& system) : _system(sysetm)
   {
   }
}

then you can finally change the assignmend of Job like

waitQueue_.push_back(Job(jobRequest.getName(), jobRequest.getProcessingRequirements(),
jobRequest.getTicksRequired(),
_system.getPID()
);

Also, the global can be removed

    System system_;
    Scheduler scheduler(system_);
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now