1

I was given the the following main function and I have to code the object to pass.

Here's main:

#include <iostream>
#include <string>
#include <ctime>
#include <stdexcept>
#include "ToDo.h"
using namespace std;

int getRand(int min, int range) {
    return (rand() % range) + min;     
}


const unsigned int NUM_VERB = 4;
const unsigned int NUM_ACTIVITY = 7;

const string VERB[] = { "Play", "Work on", "Practice","Eat", };
const string TARGET[] = { "homework", "dishes", "games", "guitar","vacuuming","aardvarking","coding" };

int main()
{
    srand(static_cast<unsigned int>(time(NULL))); // seed random number generator
    int numTask = getRand(3, 3); // number of tasks is 3->3+3
    ToDo** tasks = new ToDo*[numTask]; // create array of ToDo pointers, sized with numTask

    // creates new ToDo objects and keeps the pointers in tasks array
    for (int i = 0; i < numTask; i++) {
        tasks[i] = new ToDo(getRand(1, 9), VERB[rand() % NUM_VERB] + " " + TARGET[rand() % 7]);
    }

    cout << "The tasks are:\n" << "Priority\tTask\n";
    // lists the ToDo objects using the output() member
    for (int i = 0; i < numTask; i++) {
        cout << tasks[i]->output("\t\t") << endl;
    }
    cout << "\nYou should work on:\n";
    cout << ":==> " << ToDo::highestPriority()->getTask() << endl << endl;

    unsigned int increaseBy = rand() % 7 + 1;
    cout << "But if i increase the priority of: " << tasks[numTask -1]->getTask() << " by " << increaseBy << endl;

    tasks[numTask - 1]->increasePriority(increaseBy);

    cout << "\nYou should work on:\n";
    cout << ":==> " << ToDo::highestPriority()->output(": ") << endl;

    // make sure all priorities are greator than 0
    for (int i = 0; i < numTask; i++) {
        if (tasks[i]->getPriority() < 1) {
            throw invalid_argument("Invalid Priority Found!");
        }
    }

    // de-allocate memory, pointer null-ing not important as end of progran
    for (int i = 0; i < numTask; i++) {
        delete tasks[i];
    }
    delete tasks;


    getchar();

    return 0;

}

I'm confused about ToDo::highestPriority()->getTask() and ToDo::highestPriority()->output(": ") I don't know how I would use those to tell main which position in the array has the highest priority.

My running theory is to use 3 static ints as follows:

  • to keep track of the number of objects (a counter)
  • to keep track of which object has the highest priority (by making it equal counter at the highest priority), and
  • to keep track of what number the highest priority is.

I still can't figure out how to tell main which position in the array has the highest priority.

I cannot edit the main function and can only create one object, could anyone help me solve this?

typeid
  • 29
  • 7
NBell
  • 11
  • 1
  • When you say object, do you mean `class`? – Caleth Nov 22 '17 at 14:51
  • 5
    *"my prof gave me main.cpp"*. So sorry about that code :-/ – Jarod42 Nov 22 '17 at 14:52
  • yes, a .h and .cpp file that make the ToDo class – NBell Nov 22 '17 at 14:53
  • Why not just `ToDo::highestPriority()`? Why does it have to return an object whose sole purpose (it seems) is to return a task, i.e. `ToDo::highestPriority()->getTask()`? – smac89 Nov 22 '17 at 14:57
  • 1
    For me you need a `static std::vector instances;` and `static ToDo* ToDo::highestPriority()` would just do a `std::max_element`. – Jarod42 Nov 22 '17 at 15:00
  • That `getRand` function is *horrible*. Horribly biased depending on the passed in range due to the use of modulo and may overflow depending on the passed in min with nothing guarding against that. Also `rand()` eeew. – Jesper Juhl Nov 22 '17 at 15:00
  • `delete tasks;` should be `delete[] tasks;`; in fact I fail to find any line of that main which isn't wrong or wasn't already obsolete when the spice girls where #1. (edit: found one line: `}`) – YSC Nov 22 '17 at 15:48

1 Answers1

2

You need to define a class Todo, and there is existing usage of it.

Let's start with the minimal implementation that will compile:

class Todo {
public:
    static ToDo * highestPriority() { return nullptr; }

    Todo (int, std::string) {}

    int getPriority() { return {}; }
    std::string getTask() { return {}; }
    std::string output(std::string) { return {}; }

    void increasePriority(int) {}
}

Now we need to do something sensible with each of those

class ToDo;
bool todo_less(ToDo const * lhs, ToDo const * rhs) { return lhs->getPriority() < rhs->getPriority(); }

class ToDo {
    int priority;
    std::string task;
    static std::vector<ToDo*> instances;
public:
    static ToDo * highestPriority() { return *std::max_element(instances.begin(), instances.end(), todo_less); }

    ToDo (int _priority, std::string _task) : priority(_priority), task(_task) { instances.push_back(this); }
    ~ToDo() { instances.erase(std::find(instances.begin(), instances.end(), this)); }

    int getPriority() const { return priority; }
    std::string getTask() const { return task; }
    std::string output(std::string joiner) const { return to_string(priority) + joiner + task; }

    void increasePriority(int inc) { priority += inc; }
}
Caleth
  • 52,200
  • 2
  • 44
  • 75
  • 2
    And tell your instructor that `std::vector` is much easier to use than `ToDo**` – Caleth Nov 22 '17 at 15:13
  • 2
    In fact there is barely a *single line* in that `main` that *isn't* a textbook example of "C with inappropriate C++ keywords" – Caleth Nov 22 '17 at 15:16
  • constness can even be fixed in final version. – Jarod42 Nov 22 '17 at 15:19
  • I'd told my instructor 5 different ways we could do this that would be better and easier but he doesn't really care. – NBell Nov 22 '17 at 15:45