Reputation: 160
For avoid duplicate code, i want to build this generic structure. I want the numbers24 vector inside the scaledown24 struct to be different from the numbers32 vector inside the scaledown32 struct. So when I make a change, they won't be able to influence each other. But when I run the program, the printAddress function shows that the address of the two vectors is the same. How can i fix this. Thanks.
#include <iostream>
#include <vector>
struct ScaleDown24{
static std::vector<int> getVector() {
std::vector<int> numbers24(3);
return numbers24;
};
static inline void printAddress(std::vector<int>sumNumbers ) {
std::vector<int> *p = &sumNumbers;
std::cout << p << "\n";
}
};
struct ScaleDown32{
static std::vector<int> getVector() {
std::vector<int> numbers32(4);
return numbers32;
};
static inline void printAddress(std::vector<int>sumNumbers ) {
std::vector<int> *p = &sumNumbers;
std::cout << p << "\n";
}
};
template<typename ScaleFunction>
void scaleDown(){
std::vector<int>sumNumbers = ScaleFunction::getVector();
ScaleFunction::printAddress(sumNumbers);
}
int main()
{
scaleDown<ScaleDown24>();
scaleDown<ScaleDown32>();
return 0;
}
Upvotes: 0
Views: 97
Reputation: 596948
There are several problems with your code. Mainly stemming from the fact that both getVector()
methods return their vectors by value, and both printAddress()
methods take their arguments by value as well. So you are dealing with copies of vectors all over the place. You are seeing memory getting reused in different contexts.
You need to introduce some references into your code to avoid those copies, eg:
#include <iostream>
#include <vector>
struct ScaleDown24{
static std::vector<int>& getVector() { // <-- return a reference
static std::vector<int> numbers24(3); // <-- make static to avoid returning a reference to a local variable
return numbers24;
};
static inline void printAddress(const std::vector<int> &sumNumbers ) { // <-- take a const reference
const std::vector<int> *p = &sumNumbers;
std::cout << p << "\n";
}
};
struct ScaleDown32{
static std::vector<int>& getVector() { // <-- return a reference
static std::vector<int> numbers32(4); // <-- make static to avoid returning a reference to a local variable
return numbers32;
};
static inline void printAddress(const std::vector<int> &sumNumbers) { // <-- take a const reference
const std::vector<int> *p = &sumNumbers;
std::cout << p << "\n";
}
};
template<typename ScaleFunction>
void scaleDown(){
std::vector<int> &sumNumbers = ScaleFunction::getVector(); // <-- save a reference, not a local copy
ScaleFunction::printAddress(sumNumbers); // <-- prints the original vector that is inside getVector()!
}
int main()
{
scaleDown<ScaleDown24>();
scaleDown<ScaleDown32>();
return 0;
}
Upvotes: 2
Reputation: 180825
Your printAddress()
function takes its argument by value. That means you are making a copy of any vector
that you pass to it, and it is that copy that you are printing the address of.
What you need to do is pass the vector argument by reference instead, so that you can get the address of the original, not a copy. That would look like this:
static inline void printAddress(std::vector<int>& sumNumbers )
// this means reference ^
You are also going to have an issue with scaleDown()
:
template<typename ScaleFunction>
void scaleDown(){
std::vector<int>sumNumbers = ScaleFunction::getVector();
ScaleFunction::printAddress(sumNumbers);
}
because sumNumbers
is a non-static local variable so it can have the same address each time you call that function. If you just want each ScaleFunction
to have its own vector, you can make it `static to do that like this:
template<typename ScaleFunction>
void scaleDown(){
static std::vector<int>sumNumbers = ScaleFunction::getVector();
ScaleFunction::printAddress(sumNumbers);
}
Also note that since printAddress()
doesn't modify the vector, and you don't want it to, you can make the vector const
to help enforce that. That would give you this:
static inline void printAddress(const std::vector<int>& sumNumbers ) {
// no need for the pointer here
std::cout << &sumNumbers << "\n";
}
Upvotes: 3