Search code examples
c++dynamic-arrays

Creating a dynamic array with Class Pointers


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.


Solution

  • 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);
    }