So far to my understanding, when defining a pointer variable, we are allocating space in RAM for that variable.
int *p;
Would define a space in RAM. Then we assign a memory address to that pointer using `&variable'.
I'm looking over at an example on: *this vs this in C++
The code is:
#include <iostream>
class Foo
{
public:
Foo()
{
this->value = 0;
}
Foo get_copy()
{
return *this;
}
Foo& get_copy_as_reference()
{
return *this;
}
Foo* get_pointer()
{
return this;
}
void increment()
{
this->value++;
}
void print_value()
{
std::cout << this->value << std::endl;
}
private:
int value;
};
int main()
{
Foo foo;
foo.increment();
foo.print_value();
foo.get_copy().increment();
foo.print_value();
foo.get_copy_as_reference().increment();
foo.print_value();
foo.get_pointer()->increment();
foo.print_value();
return 0;
}
I don't understand what the purpose of putting the * operator in front Foo* get_copy() and Foo* get_pointer() does. Why do I get an error if I removed the * from the Foo* functions while returning this not *this?
edit:
Also, why is:
foo.get_copy().increment();
foo.print_value();
yielding 1 not 2?
I don't understand what the purpose of putting the * operator in front Foo* get_copy() and Foo* get_pointer() does
Foo* get_pointer()
Foo* is a pointer that points to Foo object.
this is also a pointer that implicitly bind to the calling object of the member function. That's why the return type of those functions are Foo* not Foo.
The * is part of the type. So int means type int, and
int* type pointer to int. If the function returns pointer
to int, it is int* foo(), and if it retu rns a pointer to
Foo, it is Foo* Foo::get_pointer().
The definition reserves space for the defined object. A
declaration doesn't reserve any space, and definitions of things
that aren't objects (e.g. references or functions) don't reserve
any space either, at least not that you can see. (Obviously, a
function does exist somewhere in memory, and in many cases, the
compiler will need space as well for its implementation of a
reference. But they are invisible within the scope of C++.)
this, is always a pointer in C++, though you don't mention it explicitly anywhere. So while returning a this pointer, should use Foo*
this is actually an implicit object passed during function call, which is a pointer to the object which calls the function
It seems that you have changed the code from the example that you refer to so that get_copy() no longer returns a copy.
There are 2 ways of using * in your code example. One is for type declaration and the other is the dereferencing operator.
First the type declarations:
int *p means declaring p as a variable of type "pointer to an int".
Foo *get_pointer() means that the function get_pointer will return a value of type "pointer to a Foo object".
Now the dereferencing:
*p means "the value that p points to".
int a = 42;
int *p; // p is of type "pointer to an int"
p = &a; // set p to the address of a (p now "points to" a)
a = 117; // change the value of a
int x = *p; // set x to the value that p points to (which is a) - x will be 117
this is just a pointer to the object. *this means "the object that this points to". In your example this is of type Foo* (pointer to a Foo object) while *this is of type Foo (a Foo object).
"this" is a pointer.
you want to return a pointer to the instance (a specific allocated object).
Foo* get_pointer(){
return this;
}
or you want to return a pointer to the copy, allocate a new object.
//need to implement the copy here
Foo* get_copy(){
return this;
}
and not to the reference (address of the instance). this is why you need to return the pointer.
Related
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What are the differences between pointer variable and reference variable in C++?
This is confusing me:
class CDummy
{
public:
int isitme (CDummy& param);
};
int CDummy::isitme (CDummy& param)
{
if (¶m == this)
{
return true; //ampersand sign on left side??
}
else
{
return false;
}
}
int main ()
{
CDummy a;
CDummy* b = &a;
if ( b->isitme(a) )
{
cout << "yes, &a is b";
}
return 0;
}
In C & usually means the address of a var. What does it mean here? Is this a fancy way of pointer notation?
The reason I am assuming it is a pointer notation because this is a pointer after all and we are checking for equality of two pointers.
I am studying from cplusplus.com and they have this example.
The & has more the one meanings:
1) take the address of a variable
int x;
void* p = &x;
//p will now point to x, as &x is the address of x
2) pass an argument by reference to a function
void foo(CDummy& x);
//you pass x by reference
//if you modify x inside the function, the change will be applied to the original variable
//a copy is not created for x, the original one is used
//this is preffered for passing large objects
//to prevent changes, pass by const reference:
void fooconst(const CDummy& x);
3) declare a reference variable
int k = 0;
int& r = k;
//r is a reference to k
r = 3;
assert( k == 3 );
4) bitwise and operator
int a = 3 & 1; // a = 1
n) others???
To start, note that
this
is a special pointer ( == memory address) to the class its in.
First, an object is instantiated:
CDummy a;
Next, a pointer is instantiated:
CDummy *b;
Next, the memory address of a is assigned to the pointer b:
b = &a;
Next, the method CDummy::isitme(CDummy ¶m) is called:
b->isitme(a);
A test is evaluated inside this method:
if (¶m == this) // do something
Here's the tricky part. param is an object of type CDummy, but ¶m is the memory address of param. So the memory address of param is tested against another memory address called "this". If you copy the memory address of the object this method is called from into the argument of this method, this will result in true.
This kind of evaluation is usually done when overloading the copy constructor
MyClass& MyClass::operator=(const MyClass &other) {
// if a programmer tries to copy the same object into itself, protect
// from this behavior via this route
if (&other == this) return *this;
else {
// otherwise truly copy other into this
}
}
Also note the usage of *this, where this is being dereferenced. That is, instead of returning the memory address, return the object located at that memory address.
Well the CDummy& param that is declared as a parameter of the function CDummy::isitme is actually a reference which is "like" a pointer, but different. The important thing to note about references is that inside functions where they are passed as parameters, you really have a reference to the instance of the type, not "just" a pointer to it. So, on the line with the comment, the '&' is functioning just like in C, it is getting the address of the argument passed in, and comparing it to this which is, of course, a pointer to the instance of the class the method is being called on.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What are the differences between pointer variable and reference variable in C++?
This is confusing me:
class CDummy
{
public:
int isitme (CDummy& param);
};
int CDummy::isitme (CDummy& param)
{
if (¶m == this)
{
return true; //ampersand sign on left side??
}
else
{
return false;
}
}
int main ()
{
CDummy a;
CDummy* b = &a;
if ( b->isitme(a) )
{
cout << "yes, &a is b";
}
return 0;
}
In C & usually means the address of a var. What does it mean here? Is this a fancy way of pointer notation?
The reason I am assuming it is a pointer notation because this is a pointer after all and we are checking for equality of two pointers.
I am studying from cplusplus.com and they have this example.
The & has more the one meanings:
1) take the address of a variable
int x;
void* p = &x;
//p will now point to x, as &x is the address of x
2) pass an argument by reference to a function
void foo(CDummy& x);
//you pass x by reference
//if you modify x inside the function, the change will be applied to the original variable
//a copy is not created for x, the original one is used
//this is preffered for passing large objects
//to prevent changes, pass by const reference:
void fooconst(const CDummy& x);
3) declare a reference variable
int k = 0;
int& r = k;
//r is a reference to k
r = 3;
assert( k == 3 );
4) bitwise and operator
int a = 3 & 1; // a = 1
n) others???
To start, note that
this
is a special pointer ( == memory address) to the class its in.
First, an object is instantiated:
CDummy a;
Next, a pointer is instantiated:
CDummy *b;
Next, the memory address of a is assigned to the pointer b:
b = &a;
Next, the method CDummy::isitme(CDummy ¶m) is called:
b->isitme(a);
A test is evaluated inside this method:
if (¶m == this) // do something
Here's the tricky part. param is an object of type CDummy, but ¶m is the memory address of param. So the memory address of param is tested against another memory address called "this". If you copy the memory address of the object this method is called from into the argument of this method, this will result in true.
This kind of evaluation is usually done when overloading the copy constructor
MyClass& MyClass::operator=(const MyClass &other) {
// if a programmer tries to copy the same object into itself, protect
// from this behavior via this route
if (&other == this) return *this;
else {
// otherwise truly copy other into this
}
}
Also note the usage of *this, where this is being dereferenced. That is, instead of returning the memory address, return the object located at that memory address.
Well the CDummy& param that is declared as a parameter of the function CDummy::isitme is actually a reference which is "like" a pointer, but different. The important thing to note about references is that inside functions where they are passed as parameters, you really have a reference to the instance of the type, not "just" a pointer to it. So, on the line with the comment, the '&' is functioning just like in C, it is getting the address of the argument passed in, and comparing it to this which is, of course, a pointer to the instance of the class the method is being called on.
this is a pointer to the calling object (it returns the r-value).
*this is a pointer to the pointer of the calling object (it returns the value of the address).
**this is a pointer to the pointer of the pointer of the calling object (???).
&***this is a reference to the pointer of the pointer of the pointer of the calling object (???).
std::vector<int>:: iterator i = vector1.begin();
i is the pointer to its own r-value (returns its own value).
*i is the pointer of a r-value of an object contained in a vector (returns the value pointed in &value).
**i is the pointer to the pointer of a r-value of an object contained in a vector (???).
I am really confused.
Here's a sample code where we find the expression &**this:
class _Iter
{
private:
ListElem *pCurr;
const List *pList;
public:
_Iter(ListElem *pCurr, const List *list)
: pCurr_(pCurr), pList(list)
{}
T& operator*() { return pCurr_->data; }
T* operator->() { return &**this; }
};
this is a pointer to the current object.
*this is a reference to the current object, i.e. this dereferenced.
**this is the returned value of the overloaded unary operator* function called on the current object.
If the object returned from **this has an overloaded operator&() function, then &**this evaluates to the returned value of (**this).operator&(). Otherwise, &**this is the pointer to the returned value of the overloaded unary operator* function called on the current object.
Example:
#include <iostream>
struct A
{
int b;
int a;
int& operator*() {return a;}
int* test()
{
return &**this;
}
};
int main()
{
A a;
std::cout << "Address of a.a: " << a.test() << std::endl;
std::cout << "Address of a.a: " << &(*a) << std::endl;
std::cout << "Address of a.a: " << &(a.a) << std::endl;
return 0;
}
Sample output:
Address of a.a: 0x7fffbc200754
Address of a.a: 0x7fffbc200754
Address of a.a: 0x7fffbc200754
If you have a class Foo and a method of this class that use this and the object Foo obj then
this - is a value of type pointer to Foo that has a value of address of object obj
so you can write like this (for example in Foo:test()):
Foo *addr = this;
so addris a variable of type pointer to Foo that is initialized with a address value of object obj of class Foo.
All pointers in C++ can be dereferenced with *. So when you dereference a pointer to an object you get that object
Foo *addr = get_pointer_to(obj); //function that return a pointer to object
//three equivalent ways to call someMethod() of object obj of class Foo
obj.someMethod();
addr->someMethod();
(*addr).someMethod();
Upper part of code illustrates that object obj and dereferenced pointer (*addr) have the same syntax, because they are the same object.
C++ allows you to overload different language operators. So when you write (**this) the compiler looks to this and find that this is type of pointer to Foo, so dereferencing *this gives object of type Foo. Then the compiler find (* (*this)). But Foo is not a type of the pointer, so by default there is no * operator. So the compiler will returen an error and break the compilation. But if you define(overload) operator*() in class Foo then the compiler will call this method. So **this is equivalent to this->operator*() or to (*this).operator*().
The last one is operator&(). By default this operator returns a pointer to object. But of course it can be overloaded and return something else.
So &**this can return
1) an address of object that was returned by operator*() applied to the object (*this)
2) return value of method operator&() of the object that was returned by operator*() which was applied to (*this).
If there is no operator*() defined then &**this won't compile.
In addition if there is no operator*() defined and no operator&() defined then the construction of &**some_pointer will either not compile or will return (*some_pointer). And I can guarantee that (*some_pointer) will be a pointer.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What are the differences between pointer variable and reference variable in C++?
This is confusing me:
class CDummy
{
public:
int isitme (CDummy& param);
};
int CDummy::isitme (CDummy& param)
{
if (¶m == this)
{
return true; //ampersand sign on left side??
}
else
{
return false;
}
}
int main ()
{
CDummy a;
CDummy* b = &a;
if ( b->isitme(a) )
{
cout << "yes, &a is b";
}
return 0;
}
In C & usually means the address of a var. What does it mean here? Is this a fancy way of pointer notation?
The reason I am assuming it is a pointer notation because this is a pointer after all and we are checking for equality of two pointers.
I am studying from cplusplus.com and they have this example.
The & has more the one meanings:
1) take the address of a variable
int x;
void* p = &x;
//p will now point to x, as &x is the address of x
2) pass an argument by reference to a function
void foo(CDummy& x);
//you pass x by reference
//if you modify x inside the function, the change will be applied to the original variable
//a copy is not created for x, the original one is used
//this is preffered for passing large objects
//to prevent changes, pass by const reference:
void fooconst(const CDummy& x);
3) declare a reference variable
int k = 0;
int& r = k;
//r is a reference to k
r = 3;
assert( k == 3 );
4) bitwise and operator
int a = 3 & 1; // a = 1
n) others???
To start, note that
this
is a special pointer ( == memory address) to the class its in.
First, an object is instantiated:
CDummy a;
Next, a pointer is instantiated:
CDummy *b;
Next, the memory address of a is assigned to the pointer b:
b = &a;
Next, the method CDummy::isitme(CDummy ¶m) is called:
b->isitme(a);
A test is evaluated inside this method:
if (¶m == this) // do something
Here's the tricky part. param is an object of type CDummy, but ¶m is the memory address of param. So the memory address of param is tested against another memory address called "this". If you copy the memory address of the object this method is called from into the argument of this method, this will result in true.
This kind of evaluation is usually done when overloading the copy constructor
MyClass& MyClass::operator=(const MyClass &other) {
// if a programmer tries to copy the same object into itself, protect
// from this behavior via this route
if (&other == this) return *this;
else {
// otherwise truly copy other into this
}
}
Also note the usage of *this, where this is being dereferenced. That is, instead of returning the memory address, return the object located at that memory address.
Well the CDummy& param that is declared as a parameter of the function CDummy::isitme is actually a reference which is "like" a pointer, but different. The important thing to note about references is that inside functions where they are passed as parameters, you really have a reference to the instance of the type, not "just" a pointer to it. So, on the line with the comment, the '&' is functioning just like in C, it is getting the address of the argument passed in, and comparing it to this which is, of course, a pointer to the instance of the class the method is being called on.
Yes, I've seen this question and this FAQ, but I still don't understand what ->* and .* mean in C++.
Those pages provide information about the operators (such as overloading), but don't seem to explain well what they are.
What are ->* and .* in C++, and when do you need to use them as compared to -> and .?
I hope this example will clear things for you
//we have a class
struct X
{
void f() {}
void g() {}
};
typedef void (X::*pointer)();
//ok, let's take a pointer and assign f to it.
pointer somePointer = &X::f;
//now I want to call somePointer. But for that, I need an object
X x;
//now I call the member function on x like this
(x.*somePointer)(); //will call x.f()
//now, suppose x is not an object but a pointer to object
X* px = new X;
//I want to call the memfun pointer on px. I use ->*
(px ->* somePointer)(); //will call px->f();
Now, you can't use x.somePointer(), or px->somePointer() because there is no such member in class X. For that the special member function pointer call syntax is used... just try a few examples yourself ,you'll get used to it
EDIT: By the way, it gets weird for virtual member functions pointers.
For member variables:
struct Foo {
int a;
int b;
};
int main ()
{
Foo foo;
int (Foo :: * ptr);
ptr = & Foo :: a;
foo .*ptr = 123; // foo.a = 123;
ptr = & Foo :: b;
foo .*ptr = 234; // foo.b = 234;
}
Member functions are almost the same.
struct Foo {
int a ();
int b ();
};
int main ()
{
Foo foo;
int (Foo :: * ptr) ();
ptr = & Foo :: a;
(foo .*ptr) (); // foo.a ();
ptr = & Foo :: b;
(foo .*ptr) (); // foo.b ();
}
In a nutshell: You use -> and . if you know what member you want to access. And you use ->* and .* if you don't know what member you want to access.
Example with a simple intrusive list
template<typename ItemType>
struct List {
List(ItemType *head, ItemType * ItemType::*nextMemPointer)
:m_head(head), m_nextMemPointer(nextMemPointer) { }
void addHead(ItemType *item) {
(item ->* m_nextMemPointer) = m_head;
m_head = item;
}
private:
ItemType *m_head;
// this stores the member pointer denoting the
// "next" pointer of an item
ItemType * ItemType::*m_nextMemPointer;
};
When you have a normal pointer (to an object or a basic type), you would use * to dereference it:
int a;
int* b = a;
*b = 5; // we use *b to dereference b, to access the thing it points to
Conceptually, we're doing the same thing with a member function pointer:
class SomeClass
{
public: void func() {}
};
// typedefs make function pointers much easier.
// this is a pointer to a member function of SomeClass, which takes no parameters and returns void
typedef void (SomeClass::*memfunc)();
memfunc myPointer = &SomeClass::func;
SomeClass foo;
// to call func(), we could do:
foo.func();
// to call func() using our pointer, we need to dereference the pointer:
foo.*myPointer();
// this is conceptually just: foo . *myPointer ();
// likewise with a pointer to the object itself:
SomeClass* p = new SomeClass;
// normal call func()
p->func();
// calling func() by dereferencing our pointer:
p->*myPointer();
// this is conceptually just: p -> *myPointer ();
I hope that helps explain the concept. We're effectively dereferencing our pointer to the member function. It's a little more complicated than that -- it's not an absolute pointer to a function in memory, but just an offset, which is applied to foo or p above. But conceptually, we're dereferencing it, much like we would dereference a normal object pointer.
So called "pointers" to members in C++ are more like offsets, internally. You need both such a member "pointer", and an object, to reference the member in the object. But member "pointers" are used with pointer syntax, hence the name.
There are two ways you can have an object at hand: you have a reference to the object, or you have a pointer to the object.
For the reference, use .* to combine it with a member pointer, and for the pointer, use ->* to combine it with a member pointer.
However, as a rule, don't use member pointers if you can avoid it.
They obey pretty counter-intuitive rules, and they make it possible to circumvent protected access without any explicit casting, that is, inadvertently…
Cheers & hth.,
You cannot dereference pointer to members as normal pointers — because member functions require this pointer, and you have to pass it somehow. So, you need to use these two operators, with object on one side, and pointer on another, e.g. (object.*ptr)().
Consider using function and bind (std:: or boost::, depending on whether you write C++03 or 0x) instead of those, though.
Pointer-to-member access operators: .* and ->*
The pointer-to-member access operators, .* and ->*, are for dereferencing a pointer to member in combination with an object and a pointer to object, respectively. This description applies to both pointers to data members and pointers to member functions.
For example, consider the class Foo:
struct Foo {
int i;
void f();
};
If you declare a member pointer, iPtr, to an int data member of Foo:
int Foo::* iPtr;
You can initialize this member pointer iPtr so that it points to the Foo::i member:
iPtr = &Foo::i;
To dereference this pointer, you need to use it in conjunction with a Foo object.
Consider now the object foo and the pointer to object fooPtr:
Foo foo;
Foo* fooPtr = &foo;
Then, you can dereference iPtr in combination with foo or fooPtr:
foo.*iPtr = 0;
fooPtr->*iPtr = 0;
Analogously, you can use .* and ->* with pointers to function members. Note however that you will need to enclose them between parentheses because the function call operator, i.e., (), has higher precedence than both .* and ->*:
void (Foo::*memFuncPtr)() = &Foo::f;
(foo.*memFuncPtr)();
(fooPtr->*memFuncPtr)();
To conclude: you need an object to dereference a pointer to a member, and which one you use, either .* or ->* for dereferencing the pointer to member, depends on whether this needed object is directly provided or through an object pointer.
C++17 — Using std::invoke() instead
The use of both operators can be replaced since C++17 by the std::invoke function template. std::invoke provides a unified way of dereferencing member pointers regardless of whether you use them in combination with an object or an object pointer, and also regardless of whether the pointer to member corresponds to a pointer to data member or pointer to member function:
// dereference a pointer to a data member
std::invoke(iPtr, foo) = 0; // with an object
std::invoke(iPtr, fooPtr) = 0; // with an object pointer
// dereference a pointer to a member function
std::invoke(memFuncPtr, foo); // with an object
std::invoke(memFuncPtr, fooPtr); // with an object pointer
This unified syntax corresponds to the ordinary function call syntax, and it may make it easier to write generic code.