How does "this" pointer happen to point to different objects? - c++

Suppose I have a class:
class test {
public:
void print();
private:
int x;
};
void test::print()
{
cout<< this->x;
}
and I have these variable definitions:
test object1;
test object2;
When I call object1.print() this happens to store address of object1 and so I get x from object1 printed and when I call object2.print() this happens to store address of object2 and I get x from object2 printed. How does it happen?

Each non-static member function has an implicit hidden "current object" parameter that is exposed to you as this pointer.
So you can think that for
test::print();
there's some
test_print( test* this );
global function and so when you write
objectX.print();
in your code the compiler inserts a call to
test_print(&objectX);
and this way the member function knows the address of "the current" object.

You can think of the this pointer being an implicit argument to the functions. Imagine a little class like
class C {
public:
C( int x ) : m_x( x ) { }
void increment( int value ) {
m_x += value; // same as 'this->m_x += value'
}
int multiply( int times ) const {
return m_x * times; // same as 'return this->m_x * times;'
}
private:
int m_x;
};
which allows you to write code like
C two( 2 );
two.increment( 2 );
int result = two.multiply( 3 );
Now, what's actually happening is that the member functions increment and multiply are called with an extra pointer argument, pointing to the object on which the function is invoked. This pointer is known as this inside the method. The type of the this pointer is different, depending on whether the method is const (as multiply is) or not (as is the case with increment).
You can do something like it yourself as well, consider:
class C {
public:
C( int x ) : m_x( x ) { }
void increment( C * const that, int value ) {
that->m_x += value;
}
int multiply( C const * const that, int times ) const {
return that->m_x * times;
}
private:
int m_x;
};
you could write code like
C two( 2 );
two.increment( &two, 2 );
int result = two.multiply( &two, 3 );
Notice that the type of the this pointer is C const * const for the multiply function, so both the pointer itself is const but also the object being pointed to! This is why you cannot change member variables inside a const method - the this pointer has a type which forbids it. This could be resolved using the mutable keyword (I don't want to get side-tracked too far, so I'll rather not explain how that works) but even using a const_cast:
int C::multiply( int times ) const {
C * const that = const_cast<C * const>( this );
that->m_x = 0; // evil! Can modify member variable because const'ness was casted away
// ..
}
I'm mentioning this since it demonstrates that this isn't as special a pointer as it may seem, and this particular hack is often a better solution than making a member variable mutable since this hack is local to one function whereas mutable makes the variable mutable for all const methods of the class.

The way to think about it is that this is simply a pointer to the memory for whichever object you're currently working with. So if you do obj1.print(), then this = &obj1;. If you do obj2.print(), then this = &obj2;.

this has different values for different objects

Each instance of class test gets it's own copy of member variable x. Since x is unique for each instance, the value can be anything you want it to be.
The variable this, refers to the instance to which it is associated. You don't have to use the variable 'this'. You could just write:
void test::print()
{
cout << x;
}

Related

c++ class members functions: how to write these functions?

In my Object Oriented c++ course, we have to write this class that I have put below.
Point
class Point{
public:
Point( double x = 0, double y = 0 );
double getX() const;
double getY() const;
Point & setX( double x ); // mutator, returning reference to self
Point & setY( double y );
const Point & output() const;
double distance( const Point & other ) const;
private:
double xPoint, yPoint;
}; // class Point
my question is...I can't find any information on how the functions setX, setY, and output should work. They are the same type as the class itself and I have written what I would expect them to look like below. Can anyone tell me what I am doing wrong and maybe some more specifics of how these functions are working?
The setX function should change xPoint in the object, the setY should do the same for the yPoint and output should simply output them.
Point & Point::setX( double x )
{
xPoint = x;
}
Point & Point::setY( double y )
{
Ypoint = y;
}
const Point & Point::output() const
{
cout << xPoint << yPoint;
}
Just add a return *this; at the end of your setX and setY: you are returning a reference to your object, so that for example you can do: p0.setX(1.23).setY(3.45), with of course p0 an instance of Point. In the output function, put a separator between xPoint and yPoint, like a space. You say They are the same type as the class itself: don't confuse a variable type with the type returned by a function/method: the method setX, setY and output return a reference to an instance of the class to which they belong. Note that the reference returned by output is const, so you can do:
p0.setX(1.23).setY(3.45).output();
But not:
p0.output().setX(1.23);
As setX is not a const method (it doesn't declare that it won't modify the data inside the class instance to which it belongs).
You can call instead:
double x = p0.output().getX();
because getX is a const method.
Note: I am not saying you should use the methods in this way, but the point is to show what potentially you can do.
Setters are public metods thats allow you change private members of the class, they don't have return type so setX, setY should be void not Point:
void set(double x); // Declaration
void Point::setX( double x ) // Definition outside Point.h
{
xPoint = x;
}
Same with output should be void, rest is fine you can define it whatever you wish to display it, you can change it like this:
void Point::output() const
{
cout << "(" << xPoint << ", " << yPoint << ")";
}
setX() will probably change the value of the pointX member, and return a reference to the object being acted on.
So an implementation might be something like
Point &Point::setX(double xval)
{
if (IsValid(xval)) pointX = xval; // ignore invalid changes
return *this;
}
This can (assuming other member functions and operators are being used correctly) be used in things like this
#include <iostream>
// declaration of Point here
int main()
{
Point p;
std::cout << p.setX(25).setY(30).getX() << '\n';
}
While this example isn't particularly useful (it shows what is possible) the chaining of member function calls is useful in various circumstances. For example, this technique is actually the basis on which iostream insertion and extraction operators work, and allow multiple things to be inserted/extracted to/from a stream in a single statement.
The documentation of the setX and setY functions says
// mutator, returning reference to self
Your implementation does the mutation, but you've failed to complete the contract that this function is supposed to satisfy: it's supposed to return a reference to itself.
this is a pointer to the object you're invoking the method on, and so adding the line
return *this;
would complete the contract.
This is an aside, but it may help you understand why anyone would want to use such a 'strange' design.
You may be familiar with ordinary assignment being used in ways such as
a = b = 0;
if((result = some_function()) == 0) {
// Do something in the `result == 0` case
} else {
// Do something in the `result != 0` case
}
and other similar things. The first example sets both a and b to be 0. The second example stores the return value of the function call into the variable result, and then branches based on whether that value is 0 or not.
The way this works is that x = y is a binary operator that which has the side effect of copying the value of y into x, and then returns that value (technically a reference to x) so that it may be used in the surrounding expression.
So when you write a = b = 0, this is parsed as a = (b = 0), and has the effect of making b zero, and then evaluates to a = 0 which is then evaluated and makes a zero. Similarly for the branching example.
This is something people like to do when writing code (it's a completely separate topic whether or not this is good style), so when people design new types with operator= methods, they design them to support this usage, by making them return a reference to the object assigned to. e.g.
MyClass& MyClass::operator=(arg a)
{
// Copy the value of `a` into this object
return *this;
}
The other assignment operators, like operator+= also work this way.
Now, when you're used to this usage, it is a small step to extend it to other functions that sort of act like assignment, like setX and setY. This has the additional convenience of making it easy to chain modifications, as in point.setX(3).setY(7).

Assigning default values to arguments passed by reference

I want to do something like this:
int displayAll(Message *m, string &lastIndex, int &NumPrinted = 0 );
It gives me error, cribbing about int to int&.
I tried this too:
int temp =0;
int displayAll(Message *m, string &lastIndex, int &NumPrinted = temp );
Still it gives following error:
error: ISO C++ forbids in-class initialization of non-const static member 'temp'
Even static int temp; gives error.
error: ISO C++ forbids in-class initialization of non-const static member 'temp'
The problem with the first line of code you mention is that you are trying to pass a reference to a temporary variable
class Foo {
int displayAll(Message *m, bool &moreElements, string &lastIndex, int &NumPrinted = 0 );
};
The second bit of code complains because you were trying to initialize a class member statically.
class Foo {
int temp =0;
int displayAll(Message *m, bool &moreElements, string &lastIndex, int &NumPrinted = temp );
};
(I am putting your code inside of a class declaration to be clear about what is happening).
An easy way out of your problem that does not introduce a static variable is explicit function overloading:
class Foo {
inline int displayAll(Message *m, bool &moreElements, string &lastIndex) {
int dummy = 0;
return displayAll(m, moreElements, lastIndex, dummy);
}
int displayAll(Message *m, bool &moreElements, string &lastIndex, int &NumPrinted);
};
There's a bit of boilerplate, but it achieves what you want.
Hope this helps.
EDIT: Some more clarification. The core of the problem stems from the fact that the function must take a reference to some memory that it can modify. If you pass it a temporary variable (temporary as in the C++ meaning of the term, not just the english language term ) (as in your first line of code), it's illegal C++, since you usually copy a temporary to a value before you use it as an argument to a function:
void bar( int someNum = 0 ); // think of this as creating a temporary rvalue 0
// and then copying it into the function for use.
// temporary rvalues arise in expressions like
int v = 5 + 5; // the result of 5 + 5 is stored in a temporary rvalue, and then
// copied into v (which is an lvalue in this case).
So we need something that is an "lvalue", either some global variable somewhere or a temporary local variable ( in the english language sense ) as I gave in my answer. I was about to write a solution using a static variable, but there is a large flaw- since the static variable will be shared by all instances of your class, it will start out 0 and then be different every time you call the method ( since it would have been edted by the previous call). Even worse, in the case of multiple threads, you would be reading/writing to the same place of memory from several processors, so the value will be complete garbage, and you ill rape your processor cores' caches as each write will invalidate the cache of every other core. It's ugly, please don't do it. :P
By using my first solution you make the temporary variable very local, without much impact on anything else.
You can't do this for a non-const reference unless you declare temp to be static: see this stackoverflow post.
I fpund this interesting way of achieving this too:
class demo {
public:
void displayAll(int &x, int y = 0 ) {
int *p;
if(y)
p = (int*)y;
if(p) *p = 10;
x = 4;
}
};
int main() {
int x=0, y=0;
demo *obj = new demo();
obj->displayAll((x);
//obj->temp(x,(int)&y);
cout << "\n x= " << x << " y " << y;
return 0;
}

C++: Const correctness and pointer arguments

I understand that a const pointer can be declared a couple ways:
const int * intPtr1; // Declares a pointer that cannot be changed.
int * const intPtr2; // Declares a pointer whose contents cannot be changed.
// EDIT: THE ABOVE CLAIMS ARE INCORRECT, PLEASE READ THE ANSWERS.
But what about the same principles within the context of function arguments?
I would assume that the following is redundant:
void someFunc1(const int * arg);
void someFunc2(int * arg);
Since someFunc 1 and 2 do a pass-by-value for the pointer itself, its impossible for someFunc1 to change the value of the original pointer, in a given call to the function. To illustrate:
int i = 5;
int * iPtr = &i;
someFunc1(iPtr); // The value of iPtr is copied in and thus cannot be changed by someFunc1.
If these are true, then there is no point in ever declaring a function with a 'const int * ptr' type arg, correct?
You have it backwards:
const int * intPtr1; // Declares a pointer whose contents cannot be changed.
int * const intPtr2; // Declares a pointer that cannot be changed.
The following const is indeed unnecessary, and there's no reason to put it in a function declaration:
void someFunc1(int * const arg);
However, you might want to put it in the function implementation, for the same reason that you might want to declare a local variable (or anything else) const - the implementation may be easier to follow when you know that certain things won't change. You can do that whether or not it's declared const in any other declarations of the function.
Well it is not meant for the caller but for the code inside the someFunc1. So that any code inside someFunc1 wont accidentally change it. like
void someFunc1(int *arg) {
int i = 9;
arg = &i; // here is the issue
int j = *arg;
}
Lets do some case study:
1) Just making the pointed value const
void someFunc1(const int * arg) {
int i = 9;
*arg = i; // <- compiler error as pointed value is const
}
2) Just making the pointer const
void someFunc1(int * const arg) {
int i = 9;
arg = &i; // <- compiler error as pointer is const
}
3) Right way to use const if variables involved can be const:
void someFunc1(const int * const arg) {
int i = 9;
*arg = i; // <- compiler error as pointed value is const
arg = &i; // <- compiler error as pointer is const
}
This should clear all doubts. So I already mentioned it is meant for the function code and not for the caller and you should use the most restrictive of the 3 cases i mentioned above.
EDIT:
Even in declarations of functions its a good practice to declare const. This will not only increase readability but also the caller will be aware of the contract and has more confidence regarding immutability of arguments. (This is required bcoz you generally share your header files so caller might not have your implementation c/cpp file)
Even compiler can point out better if both declaration and definitions are in sync.
You've got your logic the wrong way round. You should read the type backwards, so const int * is a pointer to a const int and int * const is a const pointer to an int.
Example:
void foo() {
int a = 0;
int b = 0;
int * const ptrA = &a;
*ptrA = 1;
ptrA = &b; ///< Error
const int * ptrB = &a;
*ptrB = 1; ///< Error
ptrB = &b;
const int * const ptrC = &a;
*ptrC = 1; ///< Error
ptrC = &a; ///< Error
}
To elaborate and show why you would want your function parameter to be a const int * you might want to indicate to the caller that they must pass in an int because you as a function want to change the value. Consider this code for instance:
void someFunc1(const int * arg) {
// Can't change *arg in here
}
void someFunc2(int * arg) {
*arg = 5;
}
void foo() {
int a = 0;
someFunc1(&a);
someFunc2(&a);
const int b = 0;
someFunc1(&b);
someFunc2(&b); ///< *** Error here. Must pass in an int not a const int.
}
Yes, you are correct (ignoring the fact that you got them the wrong way around)- there is no sense in taking non-reference const parameters. In addition, there is no sense in returning non-reference const values.
You have it the wrong way:
const int * intPtr1; // Declares a pointer whose contents cannot be changed.
int * const intPtr2; // Declares a pointer that cannot be changed.
Generally speaking its easier to reason about constness when writting that expression slightly different: const int* is the same type as int const *. In that notation the rules are much clearer, const always applies to the type preceding it, therefore:
int const * intPtr1; // Declares a pointer to const int.
int * const intPtr2; // Declares a const pointer to int.
int const * * const * complexPtr; // A pointer to const pointer to pointer to const int
When the type is written with a leading const, the const is handled as if it was written after the first type, so const T* becomes T const *.
void someFunc2(int * arg);
Is therefore not redundant, since someFunc2 may change the contents of arg, while someFunc1 may not. void someFunc3(int * const arg); would be redundant (and ambigous) though

C++ Class design - easily init / build objects

Using C++ I built a Class that has many setter functions, as well as various functions that may be called in a row during runtime.
So I end up with code that looks like:
A* a = new A();
a->setA();
a->setB();
a->setC();
...
a->doA();
a->doB();
Not, that this is bad, but I don't like typing "a->" over and over again.
So I rewrote my class definitions to look like:
class A{
public:
A();
virtual ~A();
A* setA();
A* setB();
A* setC();
A* doA();
A* doB();
// other functions
private:
// vars
};
So then I could init my class like: (method 1)
A* a = new A();
a->setA()->setB()->setC();
...
a->doA()->doB();
(which I prefer as it is easier to write)
To give a more precise implementation of this you can see my SDL Sprite C++ Class I wrote at http://ken-soft.com/?p=234
Everything seems to work just fine. However, I would be interested in any feedback to this approach.
I have noticed One problem. If i init My class like: (method 2)
A a = A();
a.setA()->setB()->setC();
...
a.doA()->doB();
Then I have various memory issues and sometimes things don't work as they should (You can see this by changing how i init all Sprite objects in main.cpp of my Sprite Demo).
Is that normal? Or should the behavior be the same?
Edit the setters are primarily to make my life easier in initialization. My main question is way method 1 and method 2 behave different for me?
Edit: Here's an example getter and setter:
Sprite* Sprite::setSpeed(int i) {
speed = i;
return this;
}
int Sprite::getSpeed() {
return speed;
}
One note unrelated to your question, the statement A a = A(); probably isn't doing what you expect. In C++, objects aren't reference types that default to null, so this statement is almost never correct. You probably want just A a;
A a creates a new instance of A, but the = A() part invokes A's copy constructor with a temporary default constructed A. If you had done just A a; it would have just created a new instance of A using the default constructor.
If you don't explicitly implement your own copy constructor for a class, the compiler will create one for you. The compiler created copy constructor will just make a carbon copy of the other object's data; this means that if you have any pointers, it won't copy the data pointed to.
So, essentially, that line is creating a new instance of A, then constructing another temporary instance of A with the default constructor, then copying the temporary A to the new A, then destructing the temporary A. If the temporary A is acquiring resources in it's constructor and de-allocating them in it's destructor, you could run into issues where your object is trying to use data that has already been deallocated, which is undefined behavior.
Take this code for example:
struct A {
A() {
myData = new int;
std::cout << "Allocated int at " << myData << std::endl;
}
~A() {
delete myData;
std::cout << "Deallocated int at " << myData << std::endl;
}
int* myData;
};
A a = A();
cout << "a.myData points to " << a.myData << std::endl;
The output will look something like:
Allocated int at 0x9FB7128
Deallocated int at 0x9FB7128
a.myData points to 0x9FB7128
As you can see, a.myData is pointing to an address that has already been deallocated. If you attempt to use the data it points to, you could be accessing completely invalid data, or even the data of some other object that took it's place in memory. And then once your a goes out of scope, it will attempt to delete the data a second time, which will cause more problems.
What you have implemented there is called fluent interface. I have mostly encountered them in scripting languages, but there is no reason you can't use in C++.
If you really, really hate calling lots of set functions, one after the other, then you may enjoy the following code, For most people, this is way overkill for the 'problem' solved.
This code demonstrates how to create a set function that can accept set classes of any number in any order.
#include "stdafx.h"
#include <stdarg.h>
// Base class for all setter classes
class cSetterBase
{
public:
// the type of setter
int myType;
// a union capable of storing any kind of data that will be required
union data_t {
int i;
float f;
double d;
} myValue;
cSetterBase( int t ) : myType( t ) {}
};
// Base class for float valued setter functions
class cSetterFloatBase : public cSetterBase
{
public:
cSetterFloatBase( int t, float v ) :
cSetterBase( t )
{ myValue.f = v; }
};
// A couple of sample setter classes with float values
class cSetterA : public cSetterFloatBase
{
public:
cSetterA( float v ) :
cSetterFloatBase( 1, v )
{}
};
// A couple of sample setter classes with float values
class cSetterB : public cSetterFloatBase
{
public:
cSetterB( float v ) :
cSetterFloatBase( 2, v )
{}
};
// this is the class that actually does something useful
class cUseful
{
public:
// set attributes using any number of setter classes of any kind
void Set( int count, ... );
// the attributes to be set
float A, B;
};
// set attributes using any setter classes
void cUseful::Set( int count, ... )
{
va_list vl;
va_start( vl, count );
for( int kv=0; kv < count; kv++ ) {
cSetterBase s = va_arg( vl, cSetterBase );
cSetterBase * ps = &s;
switch( ps->myType ) {
case 1:
A = ((cSetterA*)ps)->myValue.f; break;
case 2:
B = ((cSetterB*)ps)->myValue.f; break;
}
}
va_end(vl);
}
int _tmain(int argc, _TCHAR* argv[])
{
cUseful U;
U.Set( 2, cSetterB( 47.5 ), cSetterA( 23 ) );
printf("A = %f B = %f\n",U.A, U.B );
return 0;
}
You may consider the ConstrOpt paradigm. I first heard about this when reading the XML-RPC C/C++ lib documentation here: http://xmlrpc-c.sourceforge.net/doc/libxmlrpc++.html#constropt
Basically the idea is similar to yours, but the "ConstrOpt" paradigm uses a subclass of the one you want to instantiate. This subclass is then instantiated on the stack with default options and then the relevant parameters are set with the "reference-chain" in the same way as you do.
The constructor of the real class then uses the constrOpt class as the only constructor parameter.
This is not the most efficient solution, but can help to get a clear and safe API design.

Passing pointer to 2D array c++

I'm having this problem for quite a long time - I have fixed sized 2D array as a class member.
class myClass
{
public:
void getpointeM(...??????...);
double * retpointM();
private:
double M[3][3];
};
int main()
{
myClass moo;
double *A[3][3];
moo.getpointM( A ); ???
A = moo.retpointM(); ???
}
I'd like to pass pointer to M matrix outside. It's probably very simple, but I just can't find the proper combination of & and * etc.
Thanks for help.
double *A[3][3]; is a 2-dimensional array of double *s. You want double (*A)[3][3];
.
Then, note that A and *A and **A all have the same address, just different types.
Making a typedef can simplify things:
typedef double d3x3[3][3];
This being C++, you should pass the variable by reference, not pointer:
void getpointeM( d3x3 &matrix );
Now you don't need to use parens in type names, and the compiler makes sure you're passing an array of the correct size.
Your intent is not clear. What is getpointeM supposed to do? Return a pointer to the internal matrix (through the parameter), or return a copy of the matrix?
To return a pointer, you can do this
// Pointer-based version
...
void getpointeM(double (**p)[3][3]) { *p = &M; }
...
int main() {
double (*A)[3][3];
moo.getpointM(&A);
}
// Reference-based version
...
void getpointeM(double (*&p)[3][3]) { p = &M; }
...
int main() {
double (*A)[3][3];
moo.getpointM(A);
}
For retpointM the declaration would look as follows
...
double (*retpointM())[3][3] { return &M; }
...
int main() {
double (*A)[3][3];
A = moo.retpointM();
}
This is rather difficult to read though. You can make it look a lot clearer if you use a typedef-name for your array type
typedef double M3x3[3][3];
In that case the above examples will transform into
// Pointer-based version
...
void getpointeM(M3x3 **p) { *p = &M; }
...
int main() {
M3x3 *A;
moo.getpointM(&A);
}
// Reference-based version
...
void getpointeM(M3x3 *&p) { p = &M; }
...
int main() {
double (*A)[3][3];
moo.getpointM(A);
}
// retpointM
...
M3x3 *retpointM() { return &M; }
...
int main() {
M3x3 *A;
A = moo.retpointM();
}
The short answer is that you can get a double * to the start of the array:
public:
double * getMatrix() { return &M[0][0]; }
Outside the class, though, you can't really trivially turn the double * into another 2D array directly, at least not in a pattern that I've seen used.
You could create a 2D array in main, though (double A[3][3]) and pass that in to a getPoint method, which could copy the values into the passed-in array. That would give you a copy, which might be what you want (instead of the original, modifiable, data). Downside is that you have to copy it, of course.
class myClass
{
public:
void getpointeM(double *A[3][3])
{
//Initialize array here
}
private:
double M[3][3];
};
int main()
{
myClass moo;
double *A[3][3];
moo.getpointM( A );
}
You may want to take the code in your main function which works with the 2D array of doubles, and move that into myClass as a member function. Not only would you not have to deal with the difficulty of passing a pointer for that 2D array, but code external to your class would no longer need to know the details of how your class implements A, since they would now be calling a function in myClass and letting that do the work. If, say, you later decided to allow variable dimensions of A and chose to replace the array with a vector of vectors, you wouldn't need to rewrite any calling code in order for it to work.
In your main() function:
double *A[3][3];
creates a 3x3 array of double* (or pointers to doubles). In other words, 9 x 32-bit contiguous words of memory to store 9 memory pointers.
There's no need to make a copy of this array in main() unless the class is going to be destroyed, and you still want to access this information. Instead, you can simply return a pointer to the start of this member array.
If you only want to return a pointer to an internal class member, you only really need a single pointer value in main():
double *A;
But, if you're passing this pointer to a function and you need the function to update its value, you need a double pointer (which will allow the function to return the real pointer value back to the caller:
double **A;
And inside getpointM() you can simply point A to the internal member (M):
getpointeM(double** A)
{
// Updated types to make the assignment compatible
// This code will make the return argument (A) point to the
// memory location (&) of the start of the 2-dimensional array
// (M[0][0]).
*A = &(M[0][0]);
}
Make M public instead of private. Since you want to allow access to M through a pointer, M is not encapsulated anyway.
struct myClass {
myClass() {
std::fill_n(&M[0][0], sizeof M / sizeof M[0][0], 0.0);
}
double M[3][3];
};
int main() {
myClass moo;
double (*A)[3] = moo.M;
double (&R)[3][3] = moo.M;
for (int r = 0; r != 3; ++r) {
for (int c = 0; c != 3; ++c) {
cout << A[r][c] << R[r][c] << ' ';
// notice A[r][c] and R[r][c] are the exact same object
// I'm using both to show you can use A and R identically
}
}
return 0;
}
I would, in general, prefer R over A because the all of the lengths are fixed (A could potentially point to a double[10][3] if that was a requirement) and the reference will usually lead to clearer code.