Suppose I have a class:
class A {
public:
A();
void myFunc();
};
Then at a different point in the program I create an instance of class A, and attempt to obtain a function pointer to myFunc():
A* a = new A;
//ATTEMPTS AT RETRIVING FUNCTION POINTER FOR A::MYFUNC
std::function<void()> fnptr = a->myFunc;
std::function<void()> fnptr(std::bind(A::myFunc, &a);
But both of these attempts present the error "call to non static member function without object argument"
Perhaps both of these attempts are totally off the mark, but essentially im trying to obtain a function pointer to the myFunc() function in the specific instance of a. Any help on how to do so is appreciated :)
I'm trying to obtain a function pointer to the myFunc() function
Obtaining a pointer to member function for A::myFunc() can be done:
void (A::*memFuncPtr)() = &A::myFunc;
or even better, taking advantage of auto:
auto memFuncPtr = &A::myFunc;
However, to dereference this pointer (i.e., to call the member function it points to), you will eventually need an A object. This object corresponds to the one the member function will be called on.
You can dereference the pointer to member function, memFuncPtr, either in combination with an A object and the .* operator:
A a;
a.*memFuncPtr();
or in combination with a pointer to an A object and the operator ->*:
A *aPtr = new A();
aPtr->*memFuncPtr();
As a result, you would need to keep a reference to the object or a copy of it in order to create std::function<void()> out of this pointer to member function.
std::invoke
Since C++17, you can simply use the std::invoke() function template instead of .* / ->*. It unifies the syntax for the two cases exposed above:
std::invoke(memFuncPtr, a);
std::invoke(memFuncPtr, aPtr);
You need the following syntax:
std::function<void()> fnptr(std::bind(&A::myFunc, a));
You could also use a lambda expression like this:
auto fn = [a] { a->myFunc(); };
Here's a demo.
In C++ the "this" pointer points to the invoking object. However, when we call a constructor with a parameter, what does the "this" pointer point to?
For example, the following line calls the constructor:
TestManager myTest(device_name);
If I put a breakpoint inside the constructor function:
TestManager::TestManager(string device_name)
{
// bunch of code
}
What should I expect the "this" pointer pointing to?
The reason I am asking this question is that in my code, the "this" pointer is pointing to another object in my code that is not being called or used anywhere.
Thanks in advance.
this always points to the object. In the case of constructors or destructors, that means the object being constructed or destructed.
The reason I am asking this question is that in my code, the "this" pointer is pointing to another object in my code that is not being called or used anywhere.
Assuming your code is written somewhat sensibly, the object's only used after its construction has finished, so it makes sense that during the constructor, you haven't seen that particular value elsewhere yet.
'This' is pointing to an object that you are using currently. If you are writing methods, constructor, destructor, you can use 'this'. If you are writing friend functions, or static functions, you can't use 'this'.
this points to the instance of the current object being initialized. Once you reached the constructor, the necessary space for the object instance is already allocated and this points to it.
Just be careful when subclassing, and calling virtual/overriden methods from within a constructor:
Example:
class A {
A() {
this->work();
}
virtual void work() {
// ...
}
};
class B : public A {
B() {
// ...
}
void work() override {
// use some private members of B
}
};
In this case, working with private members from A from within A's constructor is fine. But since derived classes' members are initialized (and allocated!) after the base class, the private members of B are invalid until you reached B's constructor. So your program will most probably crash if you run into this situation.
Other than that, I cannot think of any problems with using this in the constructor of A.
Is there a way to call a function in init list with no context of data memeber?
For example this:
class x{
public:
x(char ch): ..., foo() {} // doesn't work
...
void foo(); //foo sets the keys in keys[], different keys for different ch
private:
char keys[10];
}
instead of this:
class x{
public:
x(char ch): ... {(ch == 'a') ? foo("asdfg..."): foo("qwert..") ;}
...
void foo();
private:
char keys[10];
}
Does the init list syntax always have to be {data member name}(value)?
Also, I read that it's preferable to use init list instead of the constructor's function because this way it doesn't make a copy, but in this case does it matter?
Is there a way to call a member function in init list?
Yes.
But the result of an expression in the member initialization list must always be assigned to a member variable, so calling a void function in the member initialization list is going to need some hackery. It's possible but pointless, because the call could be just as well done in the constructor body.
What would make more sense in a member initialization list, is to call a function that returns a value that would be copied to the member. You cannot return raw arrays though, so that's not an opion unless you change the type of keys.
Also, I read that it's preferable to use init list instead of the constructor's function because this way it doesn't make a copy, but in this case does it matter?
It's true that copy-initializing a member in the member initialization list allows the copy to be elided while copy-assigning in the constructor body does not. That includes copying the return value of a function that's called in the member initialization list, but it does not apply to any copy-assignments done inside the function. You've misunderstood how the use of member initialization list can avoid copying.
Now, default initializing and copying an array 10 characters is not a lot of work. But you can minimize the amount of copying by using aggregate initialization. For that, x would have to be an aggregate. There is already an aggregate that wraps an array in the standard library since c++11: std::array. I recommend that you use that instead of x. You can write a function that returns the desired array based on the parameter.
I am new to C++ programming, but I have experience in Java. I need guidance on how to pass objects to functions in C++.
Do I need to pass pointers, references, or non-pointer and non-reference values? I remember in Java there are no such issues since we pass just the variable that holds reference to the objects.
It would be great if you could also explain where to use each of those options.
Rules of thumb for C++11:
Pass by value, except when
you do not need ownership of the object and a simple alias will do, in which case you pass by const reference,
you must mutate the object, in which case, use pass by a non-const lvalue reference,
you pass objects of derived classes as base classes, in which case you need to pass by reference. (Use the previous rules to determine whether to pass by const reference or not.)
Passing by pointer is virtually never advised. Optional parameters are best expressed as a std::optional (boost::optional for older std libs), and aliasing is done fine by reference.
C++11's move semantics make passing and returning by value much more attractive even for complex objects.
Rules of thumb for C++03:
Pass arguments by const reference, except when
they are to be changed inside the function and such changes should be reflected outside, in which case you pass by non-const reference
the function should be callable without any argument, in which case you pass by pointer, so that users can pass NULL/0/nullptr instead; apply the previous rule to determine whether you should pass by a pointer to a const argument
they are of built-in types, which can be passed by copy
they are to be changed inside the function and such changes should not be reflected outside, in which case you can pass by copy (an alternative would be to pass according to the previous rules and make a copy inside of the function)
(here, "pass by value" is called "pass by copy", because passing by value always creates a copy in C++03)
There's more to this, but these few beginner's rules will get you quite far.
There are some differences in calling conventions in C++ and Java. In C++ there are technically speaking only two conventions: pass-by-value and pass-by-reference, with some literature including a third pass-by-pointer convention (that is actually pass-by-value of a pointer type). On top of that, you can add const-ness to the type of the argument, enhancing the semantics.
Pass by reference
Passing by reference means that the function will conceptually receive your object instance and not a copy of it. The reference is conceptually an alias to the object that was used in the calling context, and cannot be null. All operations performed inside the function apply to the object outside the function. This convention is not available in Java or C.
Pass by value (and pass-by-pointer)
The compiler will generate a copy of the object in the calling context and use that copy inside the function. All operations performed inside the function are done to the copy, not the external element. This is the convention for primitive types in Java.
An special version of it is passing a pointer (address-of the object) into a function. The function receives the pointer, and any and all operations applied to the pointer itself are applied to the copy (pointer), on the other hand, operations applied to the dereferenced pointer will apply to the object instance at that memory location, so the function can have side effects. The effect of using pass-by-value of a pointer to the object will allow the internal function to modify external values, as with pass-by-reference and will also allow for optional values (pass a null pointer).
This is the convention used in C when a function needs to modify an external variable, and the convention used in Java with reference types: the reference is copied, but the referred object is the same: changes to the reference/pointer are not visible outside the function, but changes to the pointed memory are.
Adding const to the equation
In C++ you can assign constant-ness to objects when defining variables, pointers and references at different levels. You can declare a variable to be constant, you can declare a reference to a constant instance, and you can define all pointers to constant objects, constant pointers to mutable objects and constant pointers to constant elements. Conversely in Java you can only define one level of constant-ness (final keyword): that of the variable (instance for primitive types, reference for reference types), but you cannot define a reference to an immutable element (unless the class itself is immutable).
This is extensively used in C++ calling conventions. When the objects are small you can pass the object by value. The compiler will generate a copy, but that copy is not an expensive operation. For any other type, if the function will not change the object, you can pass a reference to a constant instance (usually called constant reference) of the type. This will not copy the object, but pass it into the function. But at the same time the compiler will guarantee that the object is not changed inside the function.
Rules of thumb
This are some basic rules to follow:
Prefer pass-by-value for primitive types
Prefer pass-by-reference with references to constant for other types
If the function needs to modify the argument use pass-by-reference
If the argument is optional, use pass-by-pointer (to constant if the optional value should not be modified)
There are other small deviations from these rules, the first of which is handling ownership of an object. When an object is dynamically allocated with new, it must be deallocated with delete (or the [] versions thereof). The object or function that is responsible for the destruction of the object is considered the owner of the resource. When a dynamically allocated object is created in a piece of code, but the ownership is transfered to a different element it is usually done with pass-by-pointer semantics, or if possible with smart pointers.
Side note
It is important to insist in the importance of the difference between C++ and Java references. In C++ references are conceptually the instance of the object, not an accessor to it. The simplest example is implementing a swap function:
// C++
class Type; // defined somewhere before, with the appropriate operations
void swap( Type & a, Type & b ) {
Type tmp = a;
a = b;
b = tmp;
}
int main() {
Type a, b;
Type old_a = a, old_b = b;
swap( a, b );
assert( a == old_b );
assert( b == old_a );
}
The swap function above changes both its arguments through the use of references. The closest code in Java:
public class C {
// ...
public static void swap( C a, C b ) {
C tmp = a;
a = b;
b = tmp;
}
public static void main( String args[] ) {
C a = new C();
C b = new C();
C old_a = a;
C old_b = b;
swap( a, b );
// a and b remain unchanged a==old_a, and b==old_b
}
}
The Java version of the code will modify the copies of the references internally, but will not modify the actual objects externally. Java references are C pointers without pointer arithmetic that get passed by value into functions.
There are several cases to consider.
Parameter modified ("out" and "in/out" parameters)
void modifies(T ¶m);
// vs
void modifies(T *param);
This case is mostly about style: do you want the code to look like call(obj) or call(&obj)? However, there are two points where the difference matters: the optional case, below, and you want to use a reference when overloading operators.
...and optional
void modifies(T *param=0); // default value optional, too
// vs
void modifies();
void modifies(T ¶m);
Parameter not modified
void uses(T const ¶m);
// vs
void uses(T param);
This is the interesting case. The rule of thumb is "cheap to copy" types are passed by value — these are generally small types (but not always) — while others are passed by const ref. However, if you need to make a copy within your function regardless, you should pass by value. (Yes, this exposes a bit of implementation detail. C'est le C++.)
...and optional
void uses(T const *param=0); // default value optional, too
// vs
void uses();
void uses(T const ¶m); // or optional(T param)
There's the least difference here between all situations, so choose whichever makes your life easiest.
Const by value is an implementation detail
void f(T);
void f(T const);
These declarations are actually the exact same function! When passing by value, const is purely an implementation detail. Try it out:
void f(int);
void f(int const) { /* implements above function, not an overload */ }
typedef void NC(int); // typedefing function types
typedef void C(int const);
NC *nc = &f; // nc is a function pointer
C *c = nc; // C and NC are identical types
Pass by value:
void func (vector v)
Pass variables by value when the function needs complete isolation from the environment i.e. to prevent the function from modifying the original variable as well as to prevent other threads from modifying its value while the function is being executed.
The downside is the CPU cycles and extra memory spent to copy the object.
Pass by const reference:
void func (const vector& v);
This form emulates pass-by-value behavior while removing the copying overhead. The function gets read access to the original object, but cannot modify its value.
The downside is thread safety: any change made to the original object by another thread will show up inside the function while it's still executing.
Pass by non-const reference:
void func (vector& v)
Use this when the function has to write back some value to the variable, which will ultimately get used by the caller.
Just like the const reference case, this is not thread-safe.
Pass by const pointer:
void func (const vector* vp);
Functionally same as pass by const-reference except for the different syntax, plus the fact that the calling function can pass NULL pointer to indicate it has no valid data to pass.
Not thread-safe.
Pass by non-const pointer:
void func (vector* vp);
Similar to non-const reference. The caller typically sets the variable to NULL when the function is not supposed to write back a value. This convention is seen in many glibc APIs. Example:
void func (string* str, /* ... */) {
if (str != NULL) {
*str = some_value; // assign to *str only if it's non-null
}
}
Just like all pass by reference/pointer, not thread-safe.
Since no one mentioned I am adding on it, When you pass a object to a function in c++ the default copy constructor of the object is called if you dont have one which creates a clone of the object and then pass it to the method, so when you change the object values that will reflect on the copy of the object instead of the original object, that is the problem in c++, So if you make all the class attributes to be pointers, then the copy constructors will copy the addresses of the pointer attributes , so when the method invocations on the object which manipulates the values stored in pointer attributes addresses, the changes also reflect in the original object which is passed as a parameter, so this can behave same a Java but dont forget that all your class attributes must be pointers, also you should change the values of pointers, will be much clear with code explanation.
Class CPlusPlusJavaFunctionality {
public:
CPlusPlusJavaFunctionality(){
attribute = new int;
*attribute = value;
}
void setValue(int value){
*attribute = value;
}
void getValue(){
return *attribute;
}
~ CPlusPlusJavaFuncitonality(){
delete(attribute);
}
private:
int *attribute;
}
void changeObjectAttribute(CPlusPlusJavaFunctionality obj, int value){
int* prt = obj.attribute;
*ptr = value;
}
int main(){
CPlusPlusJavaFunctionality obj;
obj.setValue(10);
cout<< obj.getValue(); //output: 10
changeObjectAttribute(obj, 15);
cout<< obj.getValue(); //output: 15
}
But this is not good idea as you will be ending up writing lot of code involving with pointers, which are prone for memory leaks and do not forget to call destructors. And to avoid this c++ have copy constructors where you will create new memory when the objects containing pointers are passed to function arguments which will stop manipulating other objects data, Java does pass by value and value is reference, so it do not require copy constructors.
Do I need to pass pointers, references, or non-pointer and non-reference values?
This is a question that matters when writing a function and choosing the types of the parameters it takes. That choice will affect how the function is called and it depends on a few things.
The simplest option is to pass objects by value. This basically creates a copy of the object in the function, which has many advantages. But sometimes copying is costly, in which case a constant reference, const&, is usually best. And sometimes you need your object to be changed by the function. Then a non-constant reference, &, is needed.
For guidance on the choice of parameter types, see the Functions section of the C++ Core Guidelines, starting with F.15. As a general rule, try to avoid raw pointers, *.
There are three methods of passing an object to a function as a parameter:
Pass by reference
pass by value
adding constant in parameter
Go through the following example:
class Sample
{
public:
int *ptr;
int mVar;
Sample(int i)
{
mVar = 4;
ptr = new int(i);
}
~Sample()
{
delete ptr;
}
void PrintVal()
{
cout << "The value of the pointer is " << *ptr << endl
<< "The value of the variable is " << mVar;
}
};
void SomeFunc(Sample x)
{
cout << "Say i am in someFunc " << endl;
}
int main()
{
Sample s1= 10;
SomeFunc(s1);
s1.PrintVal();
char ch;
cin >> ch;
}
Output:
Say i am in someFunc
The value of the pointer is -17891602
The value of the variable is 4
The following are the ways to pass a arguments/parameters to function in C++.
1. by value.
// passing parameters by value . . .
void foo(int x)
{
x = 6;
}
2. by reference.
// passing parameters by reference . . .
void foo(const int &x) // x is a const reference
{
x = 6;
}
// passing parameters by const reference . . .
void foo(const int &x) // x is a const reference
{
x = 6; // compile error: a const reference cannot have its value changed!
}
3. by object.
class abc
{
display()
{
cout<<"Class abc";
}
}
// pass object by value
void show(abc S)
{
cout<<S.display();
}
// pass object by reference
void show(abc& S)
{
cout<<S.display();
}
The question is simple and may has been discussed before, but I could find a clear answer for my case. Assume I pass a pointer object to a function
#include "foo.h"
int main()
{
foo * aFoo = new foo;
bar(aFoo);
delete aFoo;
aFoo = NULL;
return 0;
}
Then the function is written like this
void bar (foo *f)
{
f->insert();
}
The question:
Is that a call by value or call by reference? I know in call by value, there is an overhead for copying the object from main() to bar(). So I want to be sure that is a call by reference.
It is a call by value, where the value of the pointer aFoo is being copied into the function parameter f.
A call by reference is a call where the parameter is a reference, and side-effects on the argument (and not on objects possibly pointed to by that argument) which occur inside the function are visible to the caller when the function returns.
So for instance this is a function accepting a parameter by reference:
void bar(foo*& f)
// ^
// Here you are taking a pointer by reference
While this is a function accepting a parameter by value:
void bar(foo* f)
// ^
// Here you are taking a pointer to foo by value
You are probably puzzled by the fact that taking a foo by reference and writing:
void bar(foo& f)
{
f.insert();
}
Has pretty much the same effect as passing a pointer to the same foo object by value and writing:
void bar(foo* f)
{ // Precondition: f != nullptr
f->insert();
}
However, the two things are conceptually different. While the value/state of the object you passed in the first case can be different when the function returns from the value/state it had before calling the function, in the second case the value of the pointer you provided will be the same as it was before you called bar() - while the object pointed to may have undergone some state change.
Also notice, that a pointer can be null, while a reference is always bound to an object.
In your case, it is call by value in terms of the pointer to Foo formally. But since you pass a pointer to a function instead of the class instance itself, then it is conceptually call by reference in terms of the class instance since the function call does not copy the whole instance but just its pointer.
Foo fooInstance;
// providing a way to point (less formally you can call it refer) to the instance
Foo* fooPointer = &fooInstance;
// this function call is call by value (passing the value of the pointer).
// but you can logically view it as 'call by reference' to fooInstance.
bar(fooPointer);