Question about a specific class method in C++

In summary: DecimalN objects.I agree with you. Most likely, the instructor is expecting the student to modify the existing object. However, I wanted to provide a possible solution in case the instructor did want the student to return a new object. It's always best to clarify with the instructor if any confusion arises.
  • #1
diredragon
323
15
Create a class DecimalN which holds decimal numbers using dynamic arrays.

Implement a constructor DecimalN::DecimalN(char* decimal) so that it can be created like for example DecimalN number("23.5698").

Create two class functions (methods) that given the number n it shift the number n places to the right or left depending on the function.

Function prototypes:
DecimalN DecimalN::moveleft(int n); // left
DecimalN DecimalN::moveright(int n); // right

Note: No vectors and no library other than <iostream> allowed.

Here is my work:
Code:
#include <iostream>

using namespace std;

class DecimalN {
    int *whole, *fraction; //Array that keeps the parts of the number as digits
    int lng_whole, lng_frac; //Lengths of those parts.
    char sign;  //Possibly to know the sign of the function if added like "+3.45"

public:
    DecimalN(char* decimal); //This function works properly so take it as doing everything fine and given then number eg. 45.890
                              //makes whole = [4,5] and fraction = [8,9,0]
    ~DecimalN() { delete[] whole; delete[] fraction; }; //Destructor
    DecimalN moveleft(int n); //The part which i need to write.
};
I am not sure how to deal with functions that return a DecimalN. I am working with whole and fraction of the original class right? Or am i making another and then doing something with it? Before i start writing i just wanted to ask if i do work with whole and fraction of the first class, what do i return?
 
Technology news on Phys.org
  • #2
First, just to clarify, does "shift two places to the left" mean change 123.456 to 1.23456? I'll assume this below.

Warning: I'm a bit rusty on this because it's been a while since I had to do this sort of thing, so if someone else wants to jump in, feel free to do so!

It appears to me that your moveleft() member function is supposed to be used e.g. like this:

DecimalN firstNumber("123.456"); // using your constructor
DecimalN secondNumber("0.0");
secondNumber = firstNumber.moveleft(2); // secondNumber now contains "1.23456"

Your problem statement doesn't say explicitly whether firstNumber should now contain "1.23456" (the new value) or "123.456" (the old value). I think you should ask your instructor about this. If that's not possible, then choose one and document it. I personally would prefer to keep the old value, but your instructor is the "boss" here, not me!
 
  • Like
Likes FactChecker
  • #3
jtbell said:
First, just to clarify, does "shift two places to the left" mean change 123.456 to 1.23456? I'll assume this below.

Warning: I'm a bit rusty on this because it's been a while since I had to do this sort of thing, so if someone else wants to jump in, feel free to do so!

It appears to me that your moveleft() member function is supposed to be used e.g. like this:

DecimalN firstNumber("123.456"); // using your constructor
DecimalN secondNumber("0.0");
secondNumber = firstNumber.moveleft(2); // secondNumber now contains "1.23456"

Your problem statement doesn't say explicitly whether firstNumber should now contain "1.23456" (the new value) or "123.456" (the old value). I think you should ask your instructor about this. If that's not possible, then choose one and document it. I personally would prefer to keep the old value, but your instructor is the "boss" here, not me!
If i am to keep the old value i must create a new object and then return that object like eg. return number2 right?
What if i can change the old value? What do i return on the function? It is defined as DecimalN moveleft(...) so it should return some DecimalN object right?
 
  • #4
Either way, you have to return a new object, technically speaking, because firstNumber and secondNumber are different objects. Using one way (keeping the old value), you make a new DecimalN object and initialize it appropriately based on the data in the old object. The other way, you update the old object appropriately, then make a copy of it and return that.

And yes, it has to return a DecimalN object. One way (not necessarily the only way) is to have this inside moveleft():

DecimalN newNumber;
// initialize newNumber appropriately, then...
return newNumber;
 
  • #5
jtbell said:
First, just to clarify, does "shift two places to the left" mean change 123.456 to 1.23456? I'll assume this below.
That should be a rightshift (of the number, not the decimal dot).

As far as I understand the question, you should modify the existing object.
yourobject.moveright(1) converts the [4,5] and [8,9,0] to [4] and [5,8,9,0].
 
  • #6
diredragon said:
I am not sure how to deal with functions that return a DecimalN.

You are probably supposed to modify the existing DecimalN (i.e., create new arrays with the shifted digits, delete the old ones, and make whole and fraction point to the new arrays) and not create and return a new one. From what I remember from toying/learning C++ a decade ago the latter would be very complicated (at best) to do in a safe and correct way.

jtbell said:
And yes, it has to return a DecimalN object. One way (not necessarily the only way) is to have this inside moveleft():

DecimalN newNumber;
// initialize newNumber appropriately, then...
return newNumber;

I think the return invokes the destructor of newNumber, which frees the arrays storing the digits, after which they are unsafe to use.

When you do return newNumber;, C++ returns a copy of the object. C++ uses a special class method called the "copy constructor" (which you can define as part of the class) to determine how to do the copying. The default behaviour is just to copy the object members (like returning a struct in C). For arrays this means it will copy the pointers and not the contents of the arrays.

This kind of complexity and the fact that the OP makes no mention of copy constructors (or even more complicated C++ features like smart pointers) is why I think OP is not expected to write methods that construct and return new DecimalN objects.
 
  • #7
wle said:
This kind of complexity and the fact that the OP makes no mention of copy constructors (or even more complicated C++ features like smart pointers) is why I think OP is not expected to write methods that construct and return new DecimalN objects.
That was my thought also, but then why would the function not have the signature 'void moveleft (int n)'?

You're right, doing the specified return properly requires invoking the Rule of Three.
 
  • #8
jtbell said:
That was my thought also, but then why would the function not have the signature 'void moveleft (int n)'?

Good point. I hadn't noticed the methods' return types. Seems like there isn't really a sensible solution to the problem exactly as specified in the OP.

You're right, doing the specified return properly requires invoking the Rule of Three.

I never liked this. (It's the kind of thing that put me off C++ in retrospect.) It works, but then you're creating a new object only to immediately create a copy to return and destroy the original.
 
  • #9
wle said:
You are probably supposed to modify the existing DecimalN (i.e., create new arrays with the shifted digits, delete the old ones, and make whole and fraction point to the new arrays) and not create and return a new one. From what I remember from toying/learning C++ a decade ago the latter would be very complicated (at best) to do in a safe and correct way.
I think the return invokes the destructor of newNumber, which frees the arrays storing the digits, after which they are unsafe to use.

When you do return newNumber;, C++ returns a copy of the object. C++ uses a special class method called the "copy constructor" (which you can define as part of the class) to determine how to do the copying. The default behaviour is just to copy the object members (like returning a struct in C). For arrays this means it will copy the pointers and not the contents of the arrays.

This kind of complexity and the fact that the OP makes no mention of copy constructors (or even more complicated C++ features like smart pointers) is why I think OP is not expected to write methods that construct and return new DecimalN objects.

jtbell said:
That was my thought also, but then why would the function not have the signature 'void moveleft (int n)'?

You're right, doing the specified return properly requires invoking the Rule of Three.

wle said:
Good point. I hadn't noticed the methods' return types. Seems like there isn't really a sensible solution to the problem exactly as specified in the OP.
I never liked this. (It's the kind of thing that put me off C++ in retrospect.) It works, but then you're creating a new object only to immediately create a copy to return and destroy the original.

I think the intention is that we change the original number by shifting it to the left or to the right. In the main() function i create an object DecimalN first("123.456") and later shift it by calling the function like this first = first.moveleft(2) right?
I have created a copy constructor of the class that copies the data too and not just the pointers. Here it is:

C:
DecimalN::DecimalN(const DecimalN& decimal) {
    sign = decimal.sign;
    lng_whole = decimal.lng_whole;
    lng_frac = decimal.lng_frac;
    whole = new int[decimal.lng_whole];
    for (int i = 0; i < lng_whole; i++) whole[i] = decimal.whole[i];
    fraction = new int[decimal.lng_frac];
    for (int i = 0; i < lng_frac; i++) fraction[i] = decimal.fraction[i];
}
I have came up with something regarding the moveleft method (never mind that it might be right depending on do you look at it as move the dot or move the number) and i do create a new object copy the necessary data but when i return it my pointer array data disappears! I have read something about it and it's got to do with something that it's a temporary object so the destruct is called at the end. Here is the function:

C:
DecimalN DecimalN::moveleft(int n) {
    DecimalN numm("0.0"); //eg 123.456, n = 1;

    //I am supposing that n is lower than duz_whole for now.
    numm.sign = sign;
    int difference = 0;
    difference = lng_whole - n;        //Writing in the new object values of the whole part.
    numm.lng_whole = difference;
    numm.whole = new int[difference];
    for (int i = 0; i < difference; i++) numm.whole[i] = whole[i];

    numm.lng_frac = n + lng_frac;
    numm.fraction = new int[n + lng_frac];
    for (int i = difference; i < lng_whole; i++) numm.fraction[i - difference] = whole[i];    //Doing the same for the frac part.
    for (int i = 0; i < lng_whole; i++) numm.fraction[i + n] = fraction[i];

    return numm;
}

I went through the debugging step into mode and it seems it does create numm with the data it should have but the problem is as soom as i make to this return the pointer array go ballistic and return some -757383 numbers. How to fix this? Some solution i read says i should create numm as *numm = new DecimalN("0.0") but how do i return the object itself so i can call first = first.moveleft(2)?
 
  • #10
I saw that if i remove the destructor from the class it works fine. When i have the destructor it removes the pointer when i try to do first = first.moveleft(2). It works fine and creates the object but when it gets to the part that it actually copies it into first it calls destructor and deletes the arrays. I need the constructor so how do i work with it but not having it delete my arrays?
 

FAQ: Question about a specific class method in C++

What is a class method in C++?

A class method in C++ is a function that is defined inside a class and can only be accessed through an instance of that class. It is used to perform specific actions on objects of that class.

How do you define a class method in C++?

To define a class method in C++, you need to include the function prototype within the class declaration and then define the function outside of the class using the scope resolution operator (::).

Can a class method access private data members of the class?

Yes, a class method can access private data members of the class as it is considered a member of the class itself.

How is a class method different from a regular function in C++?

A class method is different from a regular function in C++ as it is associated with a specific class and can only be accessed through an instance of that class. It also has an implicit parameter, which is a pointer to the object on which the method is called.

Can a class method be overloaded in C++?

Yes, a class method can be overloaded in C++. This means that you can have multiple methods with the same name within the same class, as long as they have different parameters.

Similar threads

Replies
25
Views
2K
Replies
35
Views
3K
Replies
89
Views
5K
Replies
17
Views
2K
Replies
31
Views
2K
Replies
5
Views
2K
Replies
19
Views
1K
Replies
4
Views
1K
Back
Top