Comp Sci Using a custom constructor in a C++ class

Click For Summary
The discussion revolves around creating a C++ class named "Number" that utilizes custom constructors to manage a dynamic char array for storing decimal numbers. The first constructor should accept a char pointer and allocate memory based on the string's length, while the second constructor needs to handle two integer parts and calculate the combined length for the char array. Participants emphasize the importance of copying data rather than just pointers to ensure the new object maintains its own copy of the digits. Debugging techniques, such as using cout statements, are recommended to verify the correctness of the implementation. Overall, the conversation highlights the complexities of dynamic memory management in C++ without using standard libraries beyond <iostream>.
diredragon
Messages
321
Reaction score
15

Homework Statement


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 .

Homework Equations


3. The Attempt at a Solution [/B]
Code:
#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 can't realloc like in C? How do i deal with unknown sizes of dynamic arrays then?
 
Physics news on Phys.org
diredragon said:
do i need to know the length of nms and then allocate numarr?
Yes, you should do that.
diredragon said:
Also and most important, what is with this dynamic memory? I can't realloc like in C? How do i deal with unknown sizes of dynamic arrays then?
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?
 
jtbell said:
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?
No, sadly we cannot use anything other than <iostream>. Here is what i found:
Code:
#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?
    }

};
 
diredragon said:
nms.size();
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.

diredragon said:
But now i need to extract the digits and add them right?

Right. :cool:
 
Last edited:
jtbell said:
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>.
Code:
#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?
 
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:

diredragon said:
numarr = nms;

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).
 
jtbell said:
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).
Aha, so something like this?
Code:
Number(char* nms) {
        int i = 0, k =0;
        while (nms[i++] != '\0');
      
        numarr = new char[i];
      
        while (k != i+1) numarr[k] = nms[k++];
    }
 
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:
 
  • Like
Likes diredragon

Similar threads

  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 15 ·
Replies
15
Views
2K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 3 ·
Replies
3
Views
1K
  • · Replies 1 ·
Replies
1
Views
1K
  • · Replies 15 ·
Replies
15
Views
2K
  • · Replies 12 ·
Replies
12
Views
2K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 12 ·
Replies
12
Views
3K
  • · Replies 2 ·
Replies
2
Views
2K