How to use a class object in C++ as a function parameter - c++

I am not sure how to have a function that receives a class object as a parameter. Any help? Here is an example below.
#include<iostream>
void function(class object); //prototype
void function(class tempObject)
{
//do something with object
//use or change member variables
}
Basically I am just confused on how to create a function that will receive a class object as its parameters, and then to use those parameters inside the function such as tempObject.variable.
Sorry if this is kind of confusing, I am relatively new to C++.

class is a keyword that is used only* to introduce class definitions. When you declare new class instances either as local objects or as function parameters you use only the name of the class (which must be in scope) and not the keyword class itself.
e.g.
class ANewType
{
// ... details
};
This defines a new type called ANewType which is a class type.
You can then use this in function declarations:
void function(ANewType object);
You can then pass objects of type ANewType into the function. The object will be copied into the function parameter so, much like basic types, any attempt to modify the parameter will modify only the parameter in the function and won't affect the object that was originally passed in.
If you want to modify the object outside the function as indicated by the comments in your function body you would need to take the object by reference (or pointer). E.g.
void function(ANewType& object); // object passed by reference
This syntax means that any use of object in the function body refers to the actual object which was passed into the function and not a copy. All modifications will modify this object and be visible once the function has completed.
[* The class keyword is also used in template definitions, but that's a different subject.]

If you want to pass class instances (objects), you either use
void function(const MyClass& object){
// do something with object
}
or
void process(MyClass& object_to_be_changed){
// change member variables
}
On the other hand if you want to "pass" the class itself
template<class AnyClass>
void function_taking_class(){
// use static functions of AnyClass
AnyClass::count_instances();
// or create an object of AnyClass and use it
AnyClass object;
object.member = value;
}
// call it as
function_taking_class<MyClass>();
// or
function_taking_class<MyStruct>();
with
class MyClass{
int member;
//...
};
MyClass object1;

At its simplest:
#include <iostream>
using namespace std;
class A {
public:
A( int x ) : n( x ){}
void print() { cout << n << endl; }
private:
int n;
};
void func( A p ) {
p.print();
}
int main () {
A a;
func ( a );
}
Of course, you should probably be using references to pass the object, but I suspect you haven't got to them yet.

I was asking the same too. Another solution is you could overload your method:
void remove_id(EmployeeClass);
void remove_id(ProductClass);
void remove_id(DepartmentClass);
in the call the argument will fit accordingly the object you pass. but then you will have to repeat yourself
void remove_id(EmployeeClass _obj) {
int saveId = _obj->id;
...
};
void remove_id(ProductClass _obj) {
int saveId = _obj->id;
...
};
void remove_id(DepartmentClass _obj) {
int saveId = _obj->id;
...
};

holy errors The reason for the code below is to show how to not void main every function and not to type return; for functions...... instead push everything into the sediment for which is the print function prototype... if you need to use useful functions ... you will have to below.....
(p.s. this below is for people overwhelmed by these object and T templates which allow different variable declaration types(such as float and char) to use the same passed by value in a user defined function)
char arr[ ] = "This is a test";
string str(arr);
// You can also assign directly to a string.
str = "This is another string";
can anyone tell me why c++ made arrays into pass by value one at a time and the only way to eliminate spaces and punctuation is the use of string tokens. I couldn't get around the problem when i was trying to delete spaces for a palindrome...
#include <iostream>
#include <iomanip>
using namespace std;
int getgrades(float[]);
int getaverage(float[], float);
int calculateletters(float[], float, float, float[]);
int printResults(float[], float, float, float[]);
int main()
{
int i;
float maxSize=3, size;
float lettergrades[5], numericgrades[100], average;
size=getgrades(numericgrades);
average = getaverage(numericgrades, size);
printResults(numericgrades, size, average, lettergrades);
return 0;
}
int getgrades(float a[])
{
int i, max=3;
for (i = 0; i <max; i++)
{
//ask use for input
cout << "\nPlease Enter grade " << i+1 << " : ";
cin >> a[i];
//makes sure that user enters a vlue between 0 and 100
if(a[i] < 0 || a[i] >100)
{
cout << "Wrong input. Please
enter a value between 0 and 100 only." << endl;
cout << "\nPlease Reenter grade " << i+1 << " : ";
cin >> a[i];
return i;
}
}
}
int getaverage(float a[], float n)
{
int i;
float sum = 0;
if (n == 0)
return 0;
for (i = 0; i < n; i++)
sum += a[i];
return sum / n;
}
int printResults(float a[], float n, float average, float letters[])
{
int i;
cout << "Index Number | input |
array values address in memory " << endl;
for (i = 0; i < 3; i++)
{
cout <<" "<< i<<" \t\t"<<setprecision(3)<<
a[i]<<"\t\t" << &a[i] << endl;
}
cout<<"The average of your grades is: "<<setprecision(3)<<average<<endl;
}

Related

Why aren't the member functions called by value like the normal functions in c++?

In c++, the changes done to the argument inside a function aren't reflected in the actual variable if
the return value of function is void, but that's not the case with the member functions where we can
see the changes happening permanently.
#include<iostream>
using namespace std;
class Student {
public:
int age;
float marks;
Student()
{
cout << "call by default";
}
void ageInc()
{
age = age + 1;
}
};
int main()
{
Student s;
s.age = 34;
cout << s.age << endl;
s.ageInc();
cout << s.age << endl;
return 0;
}
In c++, the changes done to the argument inside a function aren't reflected in the actual variable if the return value of function is void
Changes to an argument's value has nothing at all to do with a function's return type. A void function can quite easily make changes to its arguments. Whether or not those changes are reflected back to the caller has to do with whether the argument is passed by pointer/reference or not.
but that's not the case with the member functions where we can see the changes happening permanently.
A non-static class method receives a hidden this pointer to the object it is being called on. When the method accesses a non-static member of its owning class, it is using that this pointer to access the member. So any changes made to the member are done directly to the mmeber.
Your example is roughly equivalent to the following behind the scenes:
#include <iostream>
using namespace std;
struct Student {
int age;
float marks;
};
Student_ctr(Student* const this)
{
cout << "call by default";
}
Student_dtr(Student* const this) {}
void Student_ageInc(Student* const this)
{
this->age = this->age + 1;
}
int main()
{
Student s;
Student_ctr(&s);
s.age = 34;
cout << s.age << endl;
Student_ageInc(&s);
cout << s.age << endl;
Student_dtr(&s);
return 0;
}
Because you're not changing an argument. Your example function takes no arguments. You're changing a member variable.
You could think of all members of the object as being automatic passed-by-reference parameters, but this isn't how C++ encourages you to think of them.

Is it safe to pass lambda to function that is going out of scope (lambda executes after the method returns)?

I am learning C++ so maybe my question is dumb. I am creating a function that takes a lambda as a parameter. I just want to know if its safe to call it when the lambda function goes out of scope. With code is easier to explain what I mean:
struct SomeStruct
{
// store pointer to callback function
void (*callback)(bool);
int arg1;
int arg2;
};
void some_method(int arg1, int arg2, void (*on_complete_callback)(bool))
{
SomeStruct s;
s.callback = on_complete_callback;
s.arg1 = arg1;
s.arg2 = arg2;
// this helper class will copy the struct even though it is passed by reference
SomeHelperClass->SomeQueue.enqueue( &s );
// do work on a separate task/thread
SomeHelperClass->CreateThread([](){
// get copy of struct
SomeStruct s_copy;
SomeHelperClass->SomeQueue.dequeue( &s_copy );
// do work that takes time to complete
// IS IT SAFE TO CALL THIS CALLBACK FUNCTION?
s_copy.callback(true);
});
}
So my question is given that code if its safe to have something like this?
void method_1()
{
void (*foo)(bool) = [](bool completedCorrectly)
{
cout << "task completed :" << completedCorrectly << endl;
};
some_method(1,2,foo);
// at this point foo should be deleted no?
// why does this work if foo is executed after method_1 completes and its stack is deleted?
// can I have code like that?
}
Edit 2
Here is the same question with working code instead of pseudo code:
#include <iostream> //for using cout
using namespace std; //for using cout
// 3 pointers
int* _X; // points to integer
int* _Y; // points to integer
void (*_F)(int); // points to function
void print_values()
{
cout << "x=" << *_X << " and y=" << *_Y << endl;
}
void some_function()
{
// create variables that live on stack of some_function
int x = 1;
int y = 2;
void (*foo)(int) = [](int someInt)
{
cout << "value passed to lambda is:" << someInt << endl;
};
// point global variables to variables created on this stack x,y and foo
_X = &x;
_Y = &y;
_F = foo;
// works
_F(11);
// works
print_values();
// when exiting variables x,y and foo should be deleted
}
int main(void)
{
// call some function
some_function();
// DOES NOT WORK (makes sense)
print_values();
// WHY DOES THIS WORK? WHY FOO IS NOT DISTROYED LIKE X AND Y?
_F(10);
return 0;
}
If I where to call that method many times and each time with a different lambda will it work? Will the callback method call the correct lambda every time?
A lambda expression is like a class. It is a blueprint for instantiating objects. Classes exist only in source code. A program actually works with objects created from the blueprint defined by a class. Lambda expressions are a source code blueprint for creating closures. Each lambda expression is transformed into a class by the compiler and instantiated into an object called closure. This class has the ability to capture values (that's that the [] part does) and take parameters (that's that the () part does) for its call operator.
Here is an example:
int main()
{
int i = 42;
auto l = [i](int const x){std::cout << x+i << '\n';};
l(2);
}
The compiler transforms this into something similar to the following (generated with https://cppinsights.io/).
int main()
{
int i = 42;
class __lambda_6_11
{
public:
inline /*constexpr */ void operator()(const int x) const
{
std::operator<<(std::cout.operator<<(x + i), '\n');
}
private:
int i;
public:
__lambda_6_11(int & _i)
: i{_i}
{}
};
__lambda_6_11 l = __lambda_6_11{i};
l.operator()(2);
}
You can see here a class that implements the call operator (operator()) with an int argument. You can also see the constructor taking an argument of type int. And then you can see the instantiation of this class at the end of main and the invocation of its call operator.
I hope this helps you understand better how lambdas work.

C++ Calling a vector inside a function through a function pointer

In a program I'm working on, I've declared a vector in main. I have two functions that use the vector: an int function, and a standard void 'print' function. I'm attempting to use a function pointer (pointing to the int function) in the void function, but I get the error that the vector has not been declared, even though it's in main. I've tried declaring the vector outside of main, and the function worked fine, but I'm hesitant on keeping it outside of main. I was wondering if there was some way to use the vector in the void function when it was declared in main. Here's some example code for what I'm asking:
// Example program
#include <iostream>
#include <vector>
using namespace std;
int returnSquare(vector<int>& numbers);
void print(int (*squarePtr)(vector<int>&));
int (*squarePtr)(vector<int>&);
int main()
{
vector<int> v(1);
squarePtr = &returnSquare;
for(int i = 0; i < v.size(); i++)
{
v.at(i) = i * 25;
cout << v.at(i) << " ";
}
print(squarePtr);
return 0;
}
int returnSquare(vector<int>& numbers)
{
int product = 0;
for(int i = 0; i < numbers.size(); i++)
{
product = numbers.at(i) * numbers.at(i);
}
return product;
}
void print(int (*squarePtr)(vector<int>&))
{
int answer = (*squarePtr)(v);
cout << answer << endl;
}
In your function print you have just one parameter. To call your squaring function you need to pass the vector to square to it, something like:
void print(int (*squarePtr)(vector<int>&), vector<int> &v)
{
int answer = (*squarePtr)(v);
cout << answer << endl;
}
Without that the variable v is not visible inside the function. The call should look like:
print(squarePtr, v);
Less important. You use the squarePtr name in your global definitions twice. This does not bring clarity to your code. You better write:
void print(int (*workerFuncPtr)(vector<int>&));
int (*squarePtr)(vector<int>&);
void print (int (*squarePtr)(vector<int>&))
This parameter only accepts a pointer to your square function, that's it. It doesn't hold a pointer or a reference to your v variable. Your print function has no idea what v is, unless you pass v as an argument, or make v a global variable (which is what you did moving it out of main).
Do this:
// Modify your print definition to accept a reference to your vector `v`
void print(int (*squarePtr)(vector<int>&), vector<int>& v);
// Add `v` as the second argument to your print call
print(squarePtr, v);
// Modify the definition of your print function to accept a reference to your vector `v`
void print(int (*squarePtr)(vector<int>&), vector<int>& v)
{
...
}

C++ variable and function

so in my main function, I have a called function with arguments stored in a variable. I run my program, and the variable containing the function is executed. I thought that when I store functions or anything in a variable, then it shouldn't execute until I tell it to.
for example:
int cycle1 = cycleList(argument1, argument2);
this statement above is now executed on my screen. Is this a correct way to write code? I wanted to store the function in a variable, and later use the variable somewhere in my code.
If you want to store a function, you need to make a pointer to the function, not call the function, which is what you're doing. Try this instead:
#include <functional>
std::function<int (int, int)> cycle1 = cycleList;
Or, if you don't have access to C++11, try this:
int (*cycle1)(int, int) = cycleList;
Then later you can call:
cycle1(argument1, argument2);
If you wanted to store the result of the function at that point in time in the program's runtime, then yes, you are doing it correctly.
Functions can accept parameters and can return a result. Where the functions are declared in your program does not matter, as long as a functions name is known to the compiler before it is called.
Let’s take a look at an example;
int Add(int num1, int num2)
{
return num1 + num2;
}
int main()
{
int result, input1, input2;
cout << "Give a integer number:";
cin >> input1;
cout << "Give another integer number:";
cin >> input2;
result = Add(input1,input2);
cout << input1 << " + " << input2 << " = " << answer;
return 0;
}
Here I defined Add() function before main() so main knows that Add() is defined. So in main() when add() calls it sends two parameter and get results with return num1+ num2 . Then it sends returned value to result.
As far as what I can get from your query is that you are calling a parameterized method in your class which is returning some value. You want to store the result of that method in a variable so that you can use it as per your need. But, you want to eliminate the overhead of computing that method even when you don't need it. It should be executed only when you require it or on the basis of a particular condition.
What I can suggest you in this case is, have this code in a condition. There must be an appropriate time or a satisfied condition when you want that method to execute and compute the result for you.
For instance:
public class BaseCondition {
public int compute(int a, int b) {
return (a + b);
}
public boolean set(boolean flag) {
flag = true;
return flag;
}
public int subtract(int a, int b) {
return (a - b);
}
public int callCompute(int a, int b) {
boolean flag = false;
int computedVal = 0;
if (a < b || a == b) {
flag = set(flag);
}
if (flag) {
computedVal = compute(a, b);
} else {
computedVal = subtract(a, b);
}
return computedVal;
}
public static void main(String[] args) {
BaseCondition obj = new BaseCondition();
int a = 11;
int b = 51;
System.out.println("Result=" + obj.callCompute(a, b));
}
}
Here, you can find compute will be called only on the basis of flag which is being set only when a condition is satisfied.
Hope it helps :)
You can also do the following using auto's
#include <iostream>
using namespace std;
int Foo()
{
return 0;
}
int main()
{
// your code goes here
auto bar = Foo;
return 0;
}
In C++, variables store values, not functions; and an expression that calls a function to get a value does so immediately. So your example calls the function to get an int value, then stores that value in the variable.
There are ways to do what you want:
// Store a lambda function object, capturing arguments to call it with.
// This doesn't call the function.
auto cycle1 = [=]{cycleList(argument1, argument2);};
// Call the function later. This calles 'cycleList' with the captured arguments.
int result = cycle1();
but you should probably learn the basics before doing this sort of thing.
Functions return results, and function objects can be stored (and copied around) themselves, including their arguments:
#include <iostream>
int cycleList(int arg1, int arg2) { return arg1 + arg2; }
struct cycleListObj
{
int arg1, arg2;
// constructor stores arguments for later use
cycleListObj(int a1, int a2): arg1(a1), arg2(a2) {}
// overload function call operator()
int operator()() { return arg1 + arg2; }
};
int main()
{
int result1 = cycleList(1, 1); // stores 2 into result1
cycleListObj fun(1, 1); // defines a function object fun with arguments 1, 1
int result2 = fun(); // calls the function object, and stores the result into result2
std::cout << result1 << result2; // outputs 22
}
Live Example
As others have shown, the C++ Standard Library defines its own generic function object std::function, but for many purposes you can define them yourself as well.
You can also store function pointer, but then you still have to supply the arguments at the call site. With a function object, you can store the arguments first, and call it later.

Functions in different files not working properly

I made a program that calls this function. I know this because "Int Strength has been called" appears in the output box. However, it will not change the values that I tell it to do.
I want it to get integer values from main(), then use them and return the new values.
I am using a header file that only contains "int strength(int a, int s, int i)"
int strength(int a, int s, int i)
{
using namespace std;
cout << "Int Strength has been called" << endl;
a = a + i;
s = s - i;
return a;
return s;
}
Multiple errors. Firstly, if you want the arguments to be modified (more precisely, the modification being effective out of the scope of the function), you have to pass the values by reference:
int strength(int &a, int &s, int &i)
Second, you seem to be concerned about return a; return s; returning two values. It doesn't - the very first return encountered exits the function immediately.
The values only change within the function. Variables are passed by value not reference.
Use references as the parameters.
int strength(int& a, int& s, int& i)
You're passing by value. You need to pass a pointer to the memory allocated in the caller that contains the data you wish to modify.
void strength(int *a, int *s, int i)
{
using namespace std;
cout << "Int Strength has been called" << endl;
*a += i;
*s -= i;
}
Then call it thusly:
a = 1;
s = 2;
i = 3;
strength(&a, &s, i);