Structures can be passed and returned from functions like any value type.
When you pass a structure to a function, the object is actually copied. That function only operates on its own local copy.
#include <iostream>
struct Point
{
int x;
int y;
};
void printPoint(Point pt)
{
std::cout << pt.x << '\n';
std::cout << pt.y << '\n';
}
int main()
{
Point p { 3, 4 };
printPoint(p);
// Return the computed value to the caller
return 0;
}
If you call the code with printPoint(p), a new Point object named pt is created in the printPoint function, with a member by member copy of the p object. Expressions pt.x and pt.y then read the members from the copied local variable. When the function finishes, the copied structure is destroyed. The caller's object p is not changed because the function has not received its address, or any way to find it. The cost of the copying grows with the size of the structure, but for small structures is negligible for the sake of producing a fully independent copy.
A function can write into the structure as well.
#include <iostream>
// Define the members that belong to this type
struct Point
{
int x;
int y;
};
void movePoint(Point pt)
{
pt.x = pt.x + 1;
pt.y = pt.y + 1;
std::cout << pt.x << '\n';
std::cout << pt.y << '\n';
}
int main()
{
Point p { 10, 20 };
movePoint(p);
std::cout << p.x << '\n';
std::cout << p.y << '\n';
return 0;
}
Inside movePoint, the statements pt.x = pt.x + 1 and pt.y = pt.y + 1 will write into a function local copy. So the two following print statements produce output 11 and 21. The two following print statements produce 10 and 20 because the writer's code cannot influence the original variables.
A function can also produce structures on its own and return them to the caller.
#include <iostream>
struct Point
{
int x;
int y;
};
Point makePoint(int a, int b)
{
Point temp { a, b };
return temp;
}
int main()
{
// Initialize p with the value returned by makePoint
Point p { makePoint(7, 8) };
std::cout << p.x << '\n';
std::cout << p.y << '\n';
return 0;
}
In the makePoint function, the value temp object p in main is initialized with a copy of temp. After the function finishes, temp is destroyed, but the values live on in the p object. The caller gets the separate, fully independent object whose members behave exactly like other Point members do.
The structure returned by the function can be used right in another expression.
#include <iostream>
struct Point
{
int x;
int y;
};
Point makePoint(int a, int b)
{
Point temp { a, b };
return temp;
}
void printPoint(Point pt)
{
std::cout << pt.x << '\n';
std::cout << pt.y << '\n';
}
int main()
{
// Call this function with the provided arguments
printPoint(makePoint(1, 2));
return 0;
}
The call makePoint(1, 2) creates a temporary Point object which is then passed to the printPoint function value, so printPoint receives a copy of the temporary object which will be destroyed at the end of the expression. Only the effect of print 1 and 2 will be seen.
Every pass by value and every return creates another separate object. Thus, structures behave much like basic types, i.e. what happens inside the function does not influence the caller if the function did not pass a structure back to the caller using return.
Exercise: Passing and Returning StructuresStarter code, hints and solutionOpenClose
Practice: Passing and Returning Structures
Work through the mission, reveal hints only when needed, and compare your result with the model solution.
Your challenge
Create Point q{1,2} and pass it to movePoint. Predict its inside-function output and then print the original q to show whether it changed.
Mission checklist
- Run the starter as a baseline, then predict the change requested in Your challenge.
- Make that change in your editor; use the lesson-specific hints if you need help.
- Compile and run your answer, then compare with the worked solution and explain the result.
Starter program
This is the working baseline, not the completed answer. Compile as C++20, then make the change described above.
#include <iostream>
// Define the members that belong to this type
struct Point
{
int x;
int y;
};
void movePoint(Point pt)
{
pt.x = pt.x + 1;
pt.y = pt.y + 1;
std::cout << pt.x << '\n';
std::cout << pt.y << '\n';
}
int main()
{
Point p { 10, 20 };
movePoint(p);
std::cout << p.x << '\n';
std::cout << p.y << '\n';
return 0;
}Hints
movePoint takes Point by value, so pt has copied coordinates. Increasing pt.x and pt.y does not move p in main.
Create q separately from p and pass q by value to movePoint. Print q after the call to distinguish the parameter copy from the caller's object.
Worked solution
The new Point q begins at (1,2). movePoint(q) prints its local copy after incrementing it to (2,3), while q remains (1,2) afterward. Passing by value does not move the original Point.
#include <iostream>
// Define the members that belong to this type
struct Point
{
int x;
int y;
};
void movePoint(Point pt)
{
pt.x = pt.x + 1;
pt.y = pt.y + 1;
std::cout << pt.x << '\n';
std::cout << pt.y << '\n';
}
int main()
{
Point p { 10, 20 };
movePoint(p);
std::cout << p.x << '\n';
std::cout << p.y << '\n';
Point q{1, 2};
movePoint(q);
std::cout << "Original q: " << q.x << ' ' << q.y << '\n';
return 0;
}
Example output
11
21
10
20
2
3
Original q: 1 2
0 comments
No comments yet. Be the first.