Passing Objects by reference - c++

(I did not find the answer I was looking for but I figure it out my self so I want to try answering my own Question for someone else who may have it in the future)
How can I pass an object to a non-Class function and change its data?
For example
class Foo{} has a private int x = 5 and I want to change it to 10 with out entering the changeValue function from the class directly but use a non-Class function to call this function.

So if your code looks something like this:
class Foo {
public:
void changeValue(int val) { x = val; }
private:
int x;
}
And you want to change the x outside the changeValue method, all you need to do is add function you want to change it in as a friend to Foo class. So for example, for this to work:
void g(Foo& foo) {
foo.x = 10;
}
You must add this line to your Foo class:
friend void g(Foo& foo);
Declaring something inside the class as a friend allows that function/class to access private members and methods.

Let's say we have
class Foo{
private:
int x;
public:
change(int y){
x = y;
}
}
and we want the function
void changeVal(Foo test, int num);
to change the X instead of
Foo::change(int y);
we would give our changeVal function the address of the object
int main(){
Foo test;
changeVal(&test, 5);
}
then we are going to create changeVal and make a pointer object to hold the address of our original object
void changeVal(Foo* test, int num){
...
}
and in the body we need to create a third object to take the value of the original object so we give it the address we stored in the "Foo* test" and change the value of the new object with the address of the original so we are changing the original instead of a copy
void changeVal(Foo* test, int num){
Foo test2 = &test;
test2.change(num);
}

Related

Is this a valid workaround to avoid "invalid use of member ‘X::XX’ in static member function"?

I was working on someone else's project, and I ran into an issue where the author's static function was preventing me from doing what I wanted. I wanted the function to modify a member variable I had created, which can't happen if the object was never instantiated.
As expected, accessing Foo::number from the static function Foo::foobar() causes this error:
staticvspointer.cpp:20:5: error: invalid use of member ‘Foo::number’ in static member function
My two options are to make the variable "number" a global, or make the function not static.
int NUMBER; //this could be global, but would make the large project messy
//class has a static function
class Foo {
public:
Foo();
static int foobar();
int number;
};
//make member function not static
class Bar {
public:
Bar();
void foobar(int);
int number;
};
Foo::Foo() {
}
int Foo::foobar() {
//can't access "number = 2;" in static function.
NUMBER = 2; //CAN access global though
return 2;
}
Bar::Bar() {
}
void Bar::foobar(int number) {
this->number = number;
}
int main() {
//1.) using a static function to get 2
int a = Foo::foobar();
int b = a + 2;
//b = 4
//2.) using a pointer to get ClassName::memberVariable, and then deleting it.
Bar* bar = new Bar;
bar->foobar(2);
b = bar->number + 2;
delete bar;
//b still = 4
//3.) using a global
Foo::foobar();
b = NUMBER + 2;
//b = 4 again
return 0;
}
I assume the problems this may or may not cause are dependent on the project, but I can't think of a reason not to do this.
Is there anything wrong with method #2? Is it a proper use of pointers? Is it readable or confusing? For some reason it feels wrong to me.

C++ global variable that can be changed only in one method, possible?

I'm looking for a way to have an int variable that persists value across method calls. From this perspective a class member will be good.
But I would like that int variable to be changed in only one particular method.
How do I make that?
I tough about
void MyClass::my_method(){
static int var = 0;
var++;
}
But, I would like var = 0; to be executed only the first time.
void my_method(){
static int var;
var++;
}
The problem here is, that
static int var;
is only visible in the local scope of my_method().
You can make it global just by definition of that variable outside of my_method():
int var;
void my_method() {
var++;
}
but var will be visible for everyone.
The better way is to encapsulate all of that into a class:
class MyClass {
public:
static void my_method() {
var++;
}
private:
static int var = 0;
};
You can use the following key access pattern:
struct Foo {
void fun1();
void fun2();
static class Var {
friend void Foo::fun1();
int i = 0;
public:
int value() const { return i; }
} var;
};
Foo::Var Foo::var;
void Foo::fun1() { var.i = 42; }
void Foo::fun2() {
// var.i = 42; // this will generate compile error cause fun2 doesn't have to var
}
Live Demo
This way only the member functions of Foo that are declared friends in wrapper class Var can change its private member variables (e.g., var.i).
var is just locally, if you want that to be 0 the first time the function returns make it initialized to -1 or if 0 is just right you are ok. As is var is only visible inside my_method so if you want that to be visible to all the class you have to put it outside and use only my_method to modify the value.
I don't have enough rep to comment yet, But you should note that Static is not equal to Constant.
Static variables maintain their value for ALL instances of a class, whereas Constant variables can have different values for each instance (object) of a class.
See this question for a more in-depth explanation.
What is the difference between a static and const variable?
To answer your question directly, you cannot have a true "Global" vairable that is only editable from one class. Instead, you should consider πάντα ῥεῖ 's answer OR wait to declare the constant until after you know the value you would like to assign to it. For instance, I want to store X+10 to a constant variable Y
int x = 5 //create variable
//Do whatever you need to do to get the value
function myFunction(){
x = x + 10;
}
const int y = x; //now Y = 15 and cannot be changed.

Is it possible change value of Member variable within "const" function?

Value of constant variable can be changed through pointer tricks, but is it possible to do something like this :
class A (){
int x;
public:
void func () const {
//change value of x here
}
}
declare x mutable
class A (){
mutable int x;
public:
void func () const {
//change value of x here
}
};
You have two options:
class C
{
public:
void const_f() const
{
x = 5; // A
auto* p_this = const_cast<C*>(this); // B
p_this->y = 5;
}
private:
mutable int x; // A
int y;
};
A: declare certain members mutable.
B: const_cast to remove constness from the this pointer.
Though this is not appreciated, but C++ provides “Backdoors” which can be used to breach its own regulations, just like dirty pointer tricks. Anyway, you can easily do this by using a casted version of “This” pointer :
class A (){
int x;
public:
void func () const {
//change value of x here
A* ptr = const_cast<A*> (this);
ptr->x= 10; //Voila ! Here you go buddy
}
}
The most important thing to understand here is bitwise/physical/concrete constness and conceptual/meaningwise/logical/abstract constness.
In short:
If the function is conceptually const, make the member data mutable.
Otherwise, make the function non-const.
Just cast 'this', this would be a dirty way to implement your program, do avoid this if you are doing a project or teamwork as others would get confused by this.
class CAST_CLASS (){
int var;
public:
void change_CAST () const {
CAST_CLASS* pointer = const_cast<CAST_CLASS*> (this);
pointer->var= 10;
}};
The other answers don't mention this, but following also modifies "x" (definitely, not advisable):
class A {
int x, &y{x}, *z{&x};
public:
void func () const
{
y = 42; // x is modified now!
*z = 29; // x is modified again!!
}
};

Static function needing to deal with members of a C++ class

I have to make some kind of bridge between two pieces of software, but am facing an issue I don't know how to deal with. Hopefully someone will have interesting and (preferably) working suggestions.
Here is the background : I have a C++ software suite. I have to replace some function within a given class with another function, which is ok. The problem is that the new function calls another function which has to be static, but has to deal with members of the class. This is this second function which is making me mad.
If the function is not static I get the following error :
error: argument of type ‘void (MyClass::)(…)’ does not match ‘void (*)(…)’
If I set it to static I get either the following error :
error: cannot call member function ‘void
MyClass::MyFunction(const double *)’ without object
or
error: ‘this’ is unavailable for static member functions
depending on if I use or not the "this" keyword ("Function()" or "this->Function()").
And finally, the class object requires some arguments which I cannot pass to the static function (I cannot modify the static function prototype), which prevents me to create a new instance within the static function itself.
How would you deal with such a case with minimal rewriting ?
Edit : Ok, here is a simplified sample on what I have to do, hoping it is clear and correct :
// This function is called by another class on an instance of MyClass
MyClass::BigFunction()
{
…
// Call of a function from an external piece of code,
// which prototype I cannot change
XFunction(fcn, some more args);
…
}
// This function has to be static and I cannot change its prototype,
// for it to be passed to XFunction. XFunction makes iterations on it
// changing parameters (likelihood maximization) which do not appear
// on this sample
void MyClass::fcn(some args, typeN& result)
{
// doesn't work because fcn is static
result = SomeComputation();
// doesn't work, for the same reason
result = this->SomeComputation();
// doesn't work either, because MyClass has many parameters
// which have to be set
MyClass *tmp = new MyClass();
result = tmp->SomeComputation();
}
Pointers to non-static member functions are a bit tricky to deal with. The simplest workaround would just be to add an opaque pointer argument to your function which you can then cast as a pointer to 'this', then do what you need with it.
Here's a very simple example:
void doSomething(int (*callback)(void *usrPtr), void *usrPtr)
{
// Do stuff...
int value = callback(usrPtr);
cout << value << "\n";
}
class MyClass
{
public:
void things()
{
value_ = 42;
doSomething(myCallback, this);
}
private:
int value_;
static int myCallback(void *usrPtr)
{
MyClass *parent = static_cast<MyClass *>(usrPtr);
return parent->value_;
}
};
int main()
{
MyClass object;
object.things();
return 0;
}
In this example myCallback() can access the private value_ through the opaque pointer.
If you want a more C++-like approach you could look into using Boost.Function and Boost.Bind which allow you to pass non-static member functions as callbacks:
void doSomething(boost::function<int ()> callback)
{
// Do stuff...
int value = callback();
cout << value << "\n";
}
class MyClass
{
public:
void things()
{
value_ = 42;
doSomething(boost::bind(&MyClass::myCallback, this));
}
private:
int value_;
int myCallback()
{
return value_;
}
};
int main()
{
MyClass object;
object.things();
return 0;
}
If you really can't change the function prototype you could use a global pointer, but that opens up all sorts of issues if you will ever have more than one instance of your class. It's just generally bad practice.
class MyClass;
static MyClass *myClass;
void doSomething(int (*callback)())
{
// Do stuff...
int value = callback();
cout << value << "\n";
}
class MyClass
{
public:
void things()
{
value_ = 42;
myClass = this;
doSomething(myCallback);
}
private:
int value_;
static int myCallback()
{
return myClass->value_;
}
};
int main()
{
MyClass object;
object.things();
return 0;
}
Following spencercw's suggestion below the initial question I tried the "static member variable that you set to point to this" solution (the global variable would have been tricky and dangerous within the context of the software suite).
Actually I figured out there was already something like this implemented in the code (which I didn't write) :
static void* currentObject;
So I just used it, as
((MyClass*)currentObject)->SomeComputation();
It does work, thanks !!!
non-reentrant and non-thread-safe way is to pass "this" address using global variable.
You can move the result = SomeComputation(); out of your static function and place it in BigFunction right before your call to the static function.

C++ Class isn't returning the correct value of my private variable

Im trying to get this program to take the users input and put that into a public function and assign it to the privateVariable, then I want it to return the value of privateVariable to main() and output it to the screen, but all it displays is the value of an undefined int ( -858993460 ). What logical problem am I having here ?
#include <iostream>
#include <string>
using namespace std;
class MyClass
{
private:
int privateVariable;
public:
int userVariable;
void setVariable(int userVariable)
{
privateVariable = userVariable;
}
int getVariable()
{
return privateVariable;
}
};
int main()
{
int userVariable;
cin >> userVariable;
MyClass object1;
MyClass object2;
object1.setVariable(userVariable);
object2.getVariable();
cout << object2.getVariable();
system("PAUSE");
return 0;
}
You are setting in object1 and getting from object2. object1 and object2 are different objects. As variable in object2 is not set, you get a garbage value.
And I see no use of public userVariable in MyClass.
You are not setting the variable. You call setVariable on object1 and getVariable on object2, so the member of object1 remains uninitialized.
object1.setVariable(5); // object1.privateVariable = 5
// object2.privateVariable -> still uninitialized
object2.getVariable(); // returns uninitialized variable
For this to work, depending on what you want:
class MyClass
{
private:
static int privateVariable;
//......
}
This way, privateVariable will be a class-scoped member, not instance-scoped. That means it has the same value for all instances of the class (and even if instances were not created). This also means you can make both your functions static:
class MyClass
{
private:
static int privateVariable;
public:
static void setVariable(int userVariable)
{
privateVariable = userVariable;
}
static int getVariable()
{
return privateVariable;
}
};
and you can call the methods without instances:
MyClass::setVariable(5); //MyClass.privateVariable = 5;
MyClass::getVariable(); //returns 5
object1.getVariable(); //returns also 5
Another option is, if you don't want static members, to set the member for both objects:
object1.setVariable(5); // object1.privateVariable = 5
// object2.privateVariable -> still uninitialized
object2.setVariable(5); //object2.privateVariable = 5
object2.getVariable(); // returns 5
Or, you could define a constructor and set the variable there:
class MyClass
{
private:
static int privateVariable;
//......
public:
MyClass()
{
privateVariable = 5;
}
}
With this, every object you create will have the member initialized to 5.
object2 does not have your variable initialized as you set it on object1, the code you posted would only work if privateVariable was static.