I am new to C programming and I am having trouble with the following code:
#include <iostream>
#include <vector>
using namespace std;
class Absolute {
public:
vector<int> nums;
Absolute(vector<int> nums) {
nums = nums; //<--- this size is not 0
}
vector<int> getNums() { return nums; }
int addr() {
int total = 0;
for(int i=0; i<nums.size(); i ) { //<--- nums.size() here is 0 even though it should not be
total = nums[i];
}
return total;
}
};
int main() {
vector<int> numbers = {1, 3, 3, 4, 5, 6, 7, 8}; //<--- passing this to addNums but still returns size of 0
Absolute addNums = Absolute(numbers);
cout << addNums.addr() << endl;
return 0;
}
My goal is to add up all the numbers in the vector
together using the addr()
method, but for some reason the size of the vector
is 0 inside of the addr()
method, so I end up printing these very large numbers:
15152333321
What is going on here? Could it be that it's not being initialized with the vector
in the first place?
CodePudding user response:
In this code:
Absolute(vector<int> nums)
{
nums = nums;
}
You encounter what I call "Highlander's Law" (There can be only one). In this function, nums
refers to the parameter nums
, not the member nums
. The member nums
is shadowed, hidden, by the parameter. So nums = nums;
means assign the parameter to itself. The member nums
is unchanged and stays at size 0.
Fix: You can change the name of one of the variables so that they do not collide. You can be extra explicit with this->nums = nums
, but there's a better and faster option: Use the member initializer list and initialize the member nums
with the correct value rather than initialize it to a default and then assign it.
Absolute(vector<int> nums): nums(nums)
{
}
You can use the same name here because there is no ambiguity. The member nums
is being initialized, so it must be the left-most nums
. It is initialized to the parameter nums
because the parameter is the current holder of the identifier nums
.
Side note: Consider passing by reference and save yourself a copy:
Absolute(const vector<int> & nums): nums(nums)
{
}
CodePudding user response:
As stated by @Eljay, you have the same name for your parameter and your member variable in Absolute constructor.
This change
Absolute(vector<int> nums) {
this->nums = nums; //<--- this size is not 0
}
should be enough for your example to work if you really want to keep the same name. I strongly suggest you to have a different name for your parameter, _nums for example.
CodePudding user response:
Here is your code btw
/*
*
*
*
*
*/
#include <iostream>
#include <vector>
using namespace std;
class Absolute {
public:
vector<int> nums;
vector<int> getNums() { return nums; }
int total;
int addr() {
for(int i=0; i<nums.size();i ) { //<--- nums.size() here is 0 even though it should not be
total = nums[i];
}
return total;
}
Absolute(vector<int> num) {
nums = num;
total = 0; //<--- this size is not 0
}
};
int main() {
vector<int> numbers;
numbers.push_back(1);
numbers.push_back(3);
numbers.push_back(3);
numbers.push_back(4);
numbers.push_back(5);
numbers.push_back(6);
numbers.push_back(7);
numbers.push_back(8);
Absolute addNums = Absolute(numbers);
cout << addNums.addr() << endl;
return 0;
}
now that the thing is there, producing right result... Please look at the fact that:
- Parameter and attributes were named the same, I don't know why you would want to do that but thats not appropriate.
- I moved 'Total' variable to the other section where is was more appropriate to initialize variables coming up for that class object.
- for some reason, My version of Sublime Text was not comfortable with your style of vector initialization, (Which was valid though), SO I used the other valid variant.