Creating a dynamic array with Class Pointers

119 Views Asked by At

I'm having trouble with a specific part of an assignment asking to create a function that would take and store numbers in an array of Numbers (the class).

class Number {
public:
    // Make a number with value 0
    Number();
    // Make a number with value val
    Number(int val);
protected:
    string value;
}

Number::Number() {
    value = "0";
}

Number::Number(int val) {
    value = to_string(val);
}

/*
* Ask user how many numbers they want entered and store the numbers in an array of Numbers.
* Set length parameter to # of numbers entered and return the array pointer to the caller.
*/

Number* getNumbersFromUser(int& length) {
    cout << "How many number would you like to enter?";
    cin >> length;
    Number *numbers = new Number[length];
    for (int i = 0; i < length; i++) {
        cout << "Enter the number value ";
        cin >> numbers[i];
    }
}

int main() {
    int length;
    Number* numbers = getNumbersFromUser(length);
    reverseAllNumbers(numbers, length);
    cout << "All the numbers in reverse are:" << endl;
    for (int i = 0; i < length; i++) {
    numbers[i].print();
    }
    delete[] numbers;
    cout<<endl;

It seems like it's specifically requested that I use dynamic arrays, but I don't understand how I can have the user input things of type Number, as the compiler is saying it's not allowed. Please ignore the reverseAllNumbers function, I believe I have that one figured out.

EDIT: I understand there's a lot of wierd things with my code. The use of string and the necessity to use an array instead of a vector are all constraints that were placed on my assignment.

2

There are 2 best solutions below

2
On BEST ANSWER

You can implement a global operator>> for your Numbers class, eg:

std::istream& operator>>(std::istream &strm, Number &n)
{
    int value;
    strm >> value; // or however you need to read the value...
    n = Number(value);
    return strm;
}

Or:

class Number {
    //...
    friend std::istream& operator>>(std::istream &strm, Number &n);
};

std::istream& operator>>(std::istream &strm, Number &n)
{
    strm >> n.value; // or however you need to read the value...
    return strm;
}

Usually when you override the global streaming operators, you should implement member methods to handle the actual streaming, and then call those methods in the global operators. This allows the class to decide how best to stream itself:

class Number {
    //...
    void readFrom(std::istream &strm);
};

void Number::readFrom(std::istream &strm)
{
    strm >> value; // or however you need to read the value...
}

std::istream& operator>>(std::istream &strm, Number &n)
{
    n.readFrom(strm);
    return strm;
}

If you are not allowed to define a custom operator>>, you can still use the readFrom() approach, at least:

for (int i = 0; i < length; i++) {
    std::cout << "Enter the number value ";
    numbers[i].readFrom(std::cin);
}
0
On

You will probably have to return number at the end of function getNumbersFromUser to avoid memory leakage. Secondly, the line cin >> number[i] means that you are taking input in a variable of type Number which is not allowed. It is only allowed for primitive data type (int, char double etc.) or some built in objects like strings. To take input in your own defined data type, you will have to overload stream extraction operator >> or you can write a member function that takes input in class data member(s) and call that function. For example if your function is like

void Number::takeInput () {
      cin >> val; 
}

Now go in function and write number[i].takeInput() instead of cin >> number[i].