If a pointer to a structure, inside one function, is dereferenced and passed as an argument to another function how does one access the structure's members inside that function?
For instance, a pointer to a structure is passed to a function like this:
main_logic_tick(&settings);
Inside the main_logic_tick function, the pointer is dereferenced and passed as an argument to another function (i.e. tick()):
void main_logic_tick(Settings* settings)
{
//...
state_machine.tick(*settings);
}
How do I access members of the stucture Settings via the settings-variable inside the tick()-function above? Is it a call by value or a call by reference? And finally, how should the function prototype for the tick()-function look like?
How do I access members of the stucture Settings via the settings-variable inside the tick()-function above? Is it a call by value or a call by reference? And finally, how should the function prototype for the tick()-function look like?
tick() can accept the Settings object by value or by reference. It sounds like you want it to accept its argument by reference -- that you want to be able modify the object and have the modifications be visible two functions upstream. For that, you would use:
void tick(Settings& settings);
Inside tick you would use the usual syntax for accessing members of a reference -- using the dot (.) operator.
settings.member = new_value;
Related
I'm new to C++ and I'm getting myself confused over concepts involving pointers/references
If I had a function such as
void func(classA *&size) {
//this is the part I don't understand what to do
}
if size had width and length, how would I change just length? (basically modify an object using *&)
Since size is a reference to the type classA*, it behaves as an alias for a pointer to a classA object, and can be used interchangeably with any other name for that object. Therefore, you would modify the object pointed to like so:
size->length = 3;
which is the same as what you would write if size had declared type classA* rather than classA*&.
The function you describe takes a reference to a pointer as an argument.
This implies that the function intends to modify the pointer itself.
This code is already smelling bad. It is essentially sharing ownership of the pointed-to object with none of the protection offered by a smart pointer (unique_ptr, shared_ptr) reference, and no annotation to indicate that this pointer is an observer (see the documentation for the soon-to-be-standard observer_ptr).
You want to know what to do inside the function. Well it depends. The argument is set up to both communicate the address of an object to the function and receive the address of a (possibly different) object from the function.
If this is what you want, you probably already know what to do.
If all you want to do is pass a reference to an object, pass just a reference. If you want to pass a pointer to the object, pass just a pointer.
If you really do want to pass in a pointer and receive a possibly different pointer, I would suggest that the function should look more like this:
classA* func(classA* a); // returns either a or another classA
Even better might be this:
std::unique_ptr<classA> func(std::unique_ptr<classA> a);
Because now intent and semantics are concreted into the interface. The caller is now unable to misuse the function (barring deliberate self-harm).
While calling pointer to member function, we need to explicitly specify this:
(this->*ptr)();
If I understand correctly, we need to do that, since automatic parameter (this) passing doesn't work in this cases (maybe because we call member function using pointer to it). So I wonder, why can't we just call it and explicitly pass this as parameter?
ptr(this); / compile error
I always wondered why there is a stylistic difference between calling a pointer to function vs calling a pointer to a member function in terms of using the de-referencing operator *, i.e.
void(*fptr)()=&f; // pointer to function f()
fptr(); // call f() via pointer to function
Foo foo; // instance of Foo
void (Foo::*fptr)()=&Foo::f; // pointer to member function f()
(foo.*fptr)(); // call foo.f() via pointer to member function
In the first part, you don't use the * operator to call f() via the function pointer, but then one must use it in calling the member function via the pointer, (foo.*fptr)(). Why this difference? Why not just use (foo.fptr)() for consistency? Is there any profound reason or just this is the way C++ was designed?
I'll be quoting stuff from C++ Common Knowledge. The related chapter is titled Pointers to member functions are not pointers. There the author explains why pointers to member functions cannot be implemented as pointer to functions. I'll be using this (the fact that they're different things) as a justification for the different syntax :
When you take the address of a non-static member function, you don't get an address; you get a pointer to member function.
(...)
As with a pointer to data member, we need an object or pointer to an object in order to dereference a pointer to member function. (...) In the case of a pointer to member function, we need the object's address to use as (or to calculate) the value of the this pointer for the function call and possibly for other reasons as well.
Note that there is no such thing as a "virtual" pointer to member function. Virtualness is a property of the member function itself, not the pointer that refers to it.
This is one reason why a pointer to member function cannot be implemented, in general, as a simple pointer to function. The implementation of the pointer to member function must store within itself information as to whether the member function to which it refers is virtual or nonvirtual, information about where to find the appropriate virtual function table pointer, an offset to be added to or subtracted from the function's this pointer and possibly other information. A pointer to member function is commonly implemented as a small structure that contains this information, although many other implementations are also in use.
Dereferencing and calling a pointer to member function usually involves examining the stored information and conditionally executing the appropriate virtual or nonvirtual function calling sequence.
IMHO considering these differences one can justify the syntax difference, although historic design choices could have played their role.
If we simply use foo.fptr, it is the same as how we call a member function, making the compiler complex. Actually, fptr is not a member function of foo. Thus *fptr shows the difference. Maybe the compile can make that happen ,and I think that's how C++ was designed now.
Code like this:
int code = pthread_create(&d->thread_id, &attr, QThreadPrivate::start, this);
which QThreadPrivate::start is a static function.
So,what use is the fourth parameter this? And what is the difference if this is replaced by NULL?
This is a common idiom. You want to start a thread, but you want that thread to operate on a specific object. So you need to pass the thread a pointer to the object you want it to operate on. If you're within a member function for that object, the this pointer points to the object you're operating on. You can't pass a pointer to a member function directly (because the type would be different), so you use a static member function whose sole purpose is to cast the this pointer back to the correct type and run a non-static member function.
If you changed this to NULL, the thread would have no idea what object it was supposed to operate on. Likely, QThreadPrivate::start would fault or fail, since it would be unable to invoke a non-static member function on the instance without a pointer to that instance.
Say you have a class that has a normal member function that takes no parameters and returns no parameters. You have some code that has no idea about your class or any of its structures. You want to give that code enough information to call that member function on a particular class instance. What do you pass it? You can't pass it a pointer to the member function because with no idea about your class, it can't call a normal class member function. Answer: You pass it a pointer to a static member function whose implementation calls the normal member function, and you pass it a pointer to the instance whose method you want it to invoke.
The fourth parameter of pthread_create is passed untouched to the thread function and allows that function to change behaviour based on that argument.
OpenGroup documentation for pthread_create, detailing this, can be found here.
In this case, it's simply passing the pointer to the current object, presumably so that the start function can use that to access member variables for the specific object.
If you pass NULL instead, the created thread will get NULL and won't be able to access object specific data (without crashing and burning badly with a null pointer dereference).
You may think that, because QThreadPrivate::start is a static function, it wouldn't be able to access non-static members any way (since it generally doesn't have an object to work on).
But that only applies to implicit access - there's nothing stopping you from accessing object data through an explicit this pointer, providing you follow the access rules (e.g., no access to private data).
The fourth parameter is passed to the thread when it starts. QThreadPrivate::start can use it (after an appropriate cast) to call an object specific member function.
I had a few questions in a technical interview that I thought I knew, but wanted to double-check (they said I passed it, but I was unsure about these):
A variable declared inside a Class Method... Can that be used outside of that method, like for instance in another method? (I said no)
Can a variable declared inside a method be passed as a parameter to another method?
(I said yes but I wasn't sure)
This is for an entry-level C++ position and I'm used to C, so I wanted to double-check my understanding of C++/OO concepts.
A variable within a class method, that's instantiated within that method and wholly contained within that method, can only be used within that method. Its lifetime is finite. Edit: to clarify, I'm not saying it can't be passed to another function call within the function scope and I'm not talking about instantiating a member variable or static variable.
Yes, you can pass it to another method if that method is called from within the method it exists. Why? Because its lifetime it tied to the parent method, not the one that is called from within the method.
Let me illustrate:
//aVar does not exist.
int foo(){
int aVar = 1; //it's been born
cout << doSomething(aVar); // still alive
return aVar; //still alive but a copy is being returned from the function. Not aVar itself!
} // it's dead, man
Normally a variable's lifetime is inside the block it's declared in. So at the end of the scope it is destroyed.
BUT there's the case of Static Local Variable which is declared inside a method, but the value is saved in memory after the block is finished. Every call to that function will "see" the value of that variable. So, you could have a trick question, that the variable CAN be used in another instance of that method.
Yes you can pass it.
Contrary to popular belief, a variable declared in a member function can be used in another member function. There are two obvious routes to this.
The first is if that member function calls another member function, passing a pointer or reference to that variable to the second member function. The variable exists from the time the first member function is called until it exits from that call; if it calls some other function during that time, that other code can use the variable (if the member function does something to give it access).
The second is if you're dealing with a static variable defined in a member function. This is (for one example) the essence of the Meyers singleton. A static variable is defined in a member function, and not only other members of the singleton, but in fact all the rest of the program that accesses the singleton object use the static variable defined in that member function.
For the second question, you're right -- a variable defined in a member function is pretty much like any other local variable. It can be passed as a parameter, just like anything else.
First Question: Yes, you are correct. Variables declared within the scope of a class method are only valid in that scope. When the method exits, that variable loses scope and is no longer usable.
Second Question: Yes, the method can call another method, using that locally scoped variable. The variable remains in scope and is usable through the duration of the second function call.
First of all.....a variable declared
inside a Class Method....can that be
used outside of that method, like for
instance in another method
In C++, no.
Secondly, can a variable declared
inside a method be passed as a
parameter for another method?
In C++, in a non-concurrent application, yes. In the case of concurrency and the receiving function takes its parameter by reference you must make sure the object you pass doesn't destruct while the receiving function uses it.
First of all.....a variable declared inside a Class Method....
can that be used outside of that method,
like for instance in another method
Sure. For example,
class Base {
public:
static Base *create_instance() {
static int variable_declared_inside_class_method = 0;
return new Base(variable_declared_inside_class_method);
}
Base(int &var_) : var(var_) {}
int inc_var() {
var++; // this method uses variable_declared_inside_class_method
}
private:
int &var;
};
Note that variable_declared_inside_class_method does not live on the stack. This is why it works here.
Secondly, can a variable declared inside a method be passed as a parameter
for another method?
Absolutely.