1. Limited time only! Sign up for a free 30min personal tutor trial with Chegg Tutors
    Dismiss Notice
Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Using a custom constructor in a C++ class

  1. Nov 6, 2017 #1

    diredragon

    User Avatar
    Gold Member

    1. The problem statement, all variables and given/known data
    I am quite new to C++. I have completed my C course and am now taking a C++ course at my college. The first problem i encountered is with classes and custom made constructors. In the first part of the problem I am supposed to create a class with a field which is a dynamic char array for storing numbers like decimal ones. I am also forbidden to use anything but <iostream>. Here is the problem:
    Create a class called Number which stores numbers in a dynamic array (number can be a decimal number) in a way that one digit is one array place. Number of digits is not limited. Implement the constructors Numbers::Numbers(char* nms); and Number::Number(int* part1, int* part2);, where part1 is left of the . and part2 right of the .
    2. Relevant equations
    3. The attempt at a solution

    Code (C):

    #include <iostream>

    using namespace std;

    class Number {
        char* numarr;

    public:
        Number(char* nms) {
            numarr = nms; //Can i do this or do i need to know the length of nms and then allocate numarr?
        }
        Number(int* part1, int* part2) {
            //This is the hard part for me. How do i insert integers into an array digit by digit? Do i convert them to strings?
        }
    };
     
    Also and most important, what is with this dynamic memory? I cant realloc like in C? How do i deal with unknown sizes of dynamic arrays then?
     
  2. jcsd
  3. Nov 6, 2017 #2

    jtbell

    User Avatar

    Staff: Mentor

    Yes, you should do that.
    The first constructor is given a char* "string" as its argument, so it should be able to find the length of that "string" (the number of digits) using a suitable standard library function.

    The second constructor is given two ints, so it should be able to find the number of digits in each, and therefore the length of the combined decimal number, by doing some calculations.

    In general, if you want to change the length of a dynamic array allocated with 'new', you have to use 'new' to allocate a new array of the desired length, copy data as necessary from the old array to the new one, use 'delete' to dispose of the old array, and then adjust your class's member data (pointer) to point to the new array.

    Using the standard C++ 'string' data type would make such gymnastics much easier (no pointers or explicit memory allocation/deallocation). Are you allowed to use that?
     
  4. Nov 6, 2017 #3

    diredragon

    User Avatar
    Gold Member

    No, sadly we cannot use anything other than <iostream>. Here is what i found:
    Code (C):

    #include <iostream>

    using namespace std;

    class Number {
        char* numarr;

    public:
        Number(char* nms) {
            int i = nms.size();
            numarr = new char[i];
           
            numarr = nms; //Is this ok now?
        }
       
        Number(int* part1, int* part2) {
            int length = 1;
        while ( part1 /= 10 )
        length++;
        while ( part2 /= 10 )
        length++
        numarr = new char[length+1] //allocating one more space for a dot
        //But now i need to extract the digits and add them right?
        }

    };
     
     
  5. Nov 6, 2017 #4

    jtbell

    User Avatar

    Staff: Mentor

    size() is for std::vector and std::string, not for arrays or pointers to arrays. There's a different library function for the length of null-terminated C-strings (char arrays). IIRC the appropriate header file is <cstring>, or string.h if your instructor prefers that. It's been a long time since I've used it, because I've always preferred std::string from <string>.

    I suggest that for debugging purposes you put a cout statement in each constructor that displays a message to tell you the contents of numarr (or rather, what it points to). Something like "Constructed 12345!". Or write a Number::Display() member function that displays the contents of a Number. I bet you have to do something like that anyway as part of the exercise. But there's less to go wrong if you simply stick a cout in the constructor for debugging.

    Right. :cool:
     
    Last edited: Nov 6, 2017
  6. Nov 6, 2017 #5

    diredragon

    User Avatar
    Gold Member

    Code (C):

    #include <iostream> //Only library I can use.

    using namespace std;

    class Number {
        char* numarr;

    public:
        Number(char* nms) {
            int i = 0;
            while (nms[i] != '\0') i++;
         
            numarr = new char[i];
       
            numarr = nms;
        }

        Number(int* part1, int* part2) {
            int length = 1;
        while ( part1 /= 10 )
        length++;
        while ( part2 /= 10 )
        length++
        numarr = new char[length+1] //allocating one more space for a dot
        //But now i need to extract the digits and add them right?
        }

    };
     
    How about now? I couldn't find a library function so i calculated myself. Is it ok? Also is the thinking for the second part good?
     
  7. Nov 6, 2017 #6

    jtbell

    User Avatar

    Staff: Mentor

    I think you've got the right idea, except maybe for "off-by-one" counting errors. Remember, you can always put in cout statements for debugging, to show you exactly what's really happening. Ah wait, I see something:

    This copies the pointer, not the data that it points to. You want a new Number object to have a separate copy of the digits (chars) from the one in the calling function (that was passed in as the argument to the constructor).
     
  8. Nov 6, 2017 #7

    diredragon

    User Avatar
    Gold Member

    Aha, so something like this?
    Code (C):

    Number(char* nms) {
            int i = 0, k =0;
            while (nms[i++] != '\0');
         
            numarr = new char[i];
         
            while (k != i+1) numarr[k] = nms[k++];
        }
     
     
  9. Nov 6, 2017 #8

    jtbell

    User Avatar

    Staff: Mentor

    Something like that, yeah, but test it to make sure that k stays in sync for both numarr and nms. Make sure k gets incremented when you think it does. I personally prefer to keep the incrementing step separate. I've never been one of those people who try to cram as many operations as possible into a single statement. :oldwink:
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook

Have something to add?
Draft saved Draft deleted



Similar Discussions: Using a custom constructor in a C++ class
  1. C++ card class errors (Replies: 28)

  2. C++ class function (Replies: 2)

Loading...