I've read my book, and there's some topics where I feel weak about:

- inline functions
- static members
- this pointer
- copy constructor

I've read some tutorials online, but they use some complicated code, and I'm a beginner programmer, so I can't understand their explanations.

Just wondering, if anyone could summarize (tell me their uses) and give me simple examples of those. That would really help me understand what I'm learning .. especially the this pointer! Thanks!

Recommended Answers

All 7 Replies

Here was also an example of the this pointer that I didn't understand: (We're transitioning from structs to class)

#include <iostream>
 using namespace std;
 
 struct Target
 {
 private:
     int pos;
     string history;
 public:
     void init();
     bool move(char dir);
     void animateHistory()const;
 };
 
 void init (Target *tp)
 {
     tp -> pos = 0;
     tp -> history = "";
 }
 
 bool move (Target* tp, char dir)
 {
     switch (dir)
     {
     default:
         return false;
     case 'L':
         tp -> pos--;
         break;
     case 'R':
         tp -> pos++;
         break;
     }
     tp -> history += dir;
     return true;
 }
 
 void animateHistory (const Target* tp)
 {
     for (int k =0; k != tp -> history.size(); k++)
         cout << tp -> history[k] << endl;
 }
 
 int main()
 {
     Target t;
     t.init();
     t.move('R');
     t.move('R');
     t.animateHistory();
 }

became this:

struct Target
{
private:
  int pos;
  string history;
public:
  void init();
  bool move(char dir);
  void animateHistory()const;
};

void Target::init ()
{
  this -> pos = 0;
  this -> history = "";
 }

bool Target::move (char dir)

{
  switch (dir)
  {
  default:
      return false;
  case 'L':

      this -> pos--;
      break;
  case 'R':
      this -> pos++;
      break;
  }
  this -> history += dir;
  return true;
}
void Target::animateHistory () const 
{
  for (int k =0; k != this -> history.size(); k++)
      cout << this -> history[k] << endl;
}
int main()
{
Target t;
t.init();     // &t will be passed as the value of the "this" pointer
t.move('R');  // &t will be passed as the value of the "this" pointer

I don't understand why we had no parameters (for the second code) for some of the public member functions, or rather how Target* tp "disappeared" from each parameter. What is the cause, and why can we do that?

from here (part of 2nd code):

public:
      void init();
      bool move(char dir);
      void animateHistory()const;

Ok, I figured I'll just point you to a site and then offer my explanation as well. Here's a good link.
http://cplusplus.com/doc/tutorial/classes2.html
This link talks about the "this" keyword and static member data/functions of a class.

This "this" keyword just means "this class".

A Copy Constructor is a special kind of constructor. For example, lets say you have a simple linked list and you want to make a complete copy of it. Dynamic memory and all. Then you would need to make a copy constructor to do this. You could also do operator overloading for the '=' operator, but that's for a later discussion.

There are two types of copying. There's shallow copying where it just copies the members functions and member data and does not copy dynamic data and there's deep copying which does copy dynamic data. Here's a quick picture I whipped up in mspaint to better illustrate my point.
[IMG]http://img297.imageshack.us/img297/240/copyao2.png[/IMG]

Copy constructors are REALLY useful when you have an array of pointers pointing to some dynamic data and you want to make a copy of it for various operations and such.

Now on to inline functions. Lets say you have two functions in your program. You have int main() and you have float FindAverage(/* your parameter list */). Now let's say you want to inline FindAverage(). What inlining a function does is tell the compiler to replace all function call of FundAverage with the code inside FindAverage. Here's some before and after compiler inline optimization.

This is the code before compiler optimization.

#include <iostream>

using namespace std;

inline void FindAverage(int, int, int&);

int main()
{
	int exam1;
	int exam2;
	int average;

	cout << "Enter exam1 score: ";
	cin >> exam1;
	cout << endl << "Enter exam2 score: ";
	cin >> exam2;

	FindAverage(exam1, exam2);

	cout << "Average has been computed" << endl;

	return 0;
}

inline void FindAverage(int exam1, int exam2, int& avg)
{
	avg = (exam1 + exam2)/2;
}

This is how the compiler would treat the code.

#include <iostream>

using namespace std;

int main()
{
	int exam1;
	int exam2;
	int average;

	cout << "Enter exam1 score: ";
	cin >> exam1;
	cout << endl << "Enter exam2 score: ";
	cin >> exam2;

	avg = (exam1 + exam2)/2;	// The code for FindAverage has 
					// been substituted in it's place.

	cout << "Average has been computed" << endl;

	return 0;
}

The benefits for this is that when you do a normal function call it pushes the current data to the stack and then jumps to the function being called. Afterwards it returns after destroying any data that the function created and pops the data from the stack. So basically the only advantage it has is in function overhead. Using inline doesn't require the stack. However it's only useful for small functions. It should only be used when the code from compiling is faster than the required overhead. It's just another technique for optimization of code.

Here's some links that will explain this concept. It probably does a better way of explaining it then I do. :)
http://cplusplus.com/doc/tutorial/functions2.html

[edit]I just noticed my explanation and code for inline function has some differentces but I think you should be able to get the point of it. :) Hope this helps![/edit]

Here was also an example of the this pointer that I didn't understand: (We're transitioning from structs to class)

#include <iostream>
 using namespace std;
 
 struct Target
 {
 private:
     int pos;
     string history;
 public:
     void init();
     bool move(char dir);
     void animateHistory()const;
 };
 
 void init (Target *tp)
 {
     tp -> pos = 0;
     tp -> history = "";
 }
 
 bool move (Target* tp, char dir)
 {
     switch (dir)
     {
     default:
         return false;
     case 'L':
         tp -> pos--;
         break;
     case 'R':
         tp -> pos++;
         break;
     }
     tp -> history += dir;
     return true;
 }
 
 void animateHistory (const Target* tp)
 {
     for (int k =0; k != tp -> history.size(); k++)
         cout << tp -> history[k] << endl;
 }
 
 int main()
 {
     Target t;
     t.init();
     t.move('R');
     t.move('R');
     t.animateHistory();
 }

became this:

struct Target
{
private:
  int pos;
  string history;
public:
  void init();
  bool move(char dir);
  void animateHistory()const;
};

void Target::init ()
{
  this -> pos = 0;
  this -> history = "";
 }

bool Target::move (char dir)

{
  switch (dir)
  {
  default:
      return false;
  case 'L':

      this -> pos--;
      break;
  case 'R':
      this -> pos++;
      break;
  }
  this -> history += dir;
  return true;
}
void Target::animateHistory () const 
{
  for (int k =0; k != this -> history.size(); k++)
      cout << this -> history[k] << endl;
}
int main()
{
Target t;
t.init();     // &t will be passed as the value of the "this" pointer
t.move('R');  // &t will be passed as the value of the "this" pointer

I don't understand why we had no parameters (for the second code) for some of the public member functions, or rather how Target* tp "disappeared" from each parameter. What is the cause, and why can we do that?

from here (part of 2nd code):

public:
      void init();
      bool move(char dir);
      void animateHistory()const;

The first example doesn't compile. It's got all sorts of errors in it, doesn't even make sense in some parts, and looks kind of crazy.

The second code example works, and it's basically using this-> inside of its member functions in front of all the variables it wants to modify, however there's no real need to do this. The following will work just as well:

struct Target
{
private:
  int pos;
  string history;
public:
  void init();
  bool move(char dir);
  void animateHistory()const;
};

void Target::init ()
{
   pos = 0;
   history = "";
 }

bool Target::move (char dir)

{
  switch (dir)
  {
  default:
      return false;
  case 'L':

      pos--;
      break;
  case 'R':
      pos++;
      break;
  }
  history += dir;
  return true;
}
void Target::animateHistory () const
{
  for (int k =0; k != history.size(); k++)
      cout <<  history[k] << endl;
}
int main()
{
Target t;
t.init();     // &t will be passed as the value of the "this" pointer
t.move('R');  // &t will be passed as the value of the "this" pointer
    return 0;
}

All I did was remove the this-> code. The most useful thing for the this pointer is storing the address of the current instance on an object. For modifying variables, nah...

Hope this helps

So would you say that for classes, the

this pointer

is not useful unless we use pointers?

Also, someone said about passing stuff implicitly, so we have the () empty parameter. Can you explain that? That's confusing me a lot.

the "this" keyword is a pointer to the class in which it's used. For example:

this->idNum

Is referring to the idNum data of the class your writing for.

So to answer your question, yes you would only need the "this" keyword if your working with pointers because it is essentially a pointer. It's the pointer of a class pointing to itself, if that makes any sense to you.

the "this" keyword is a pointer to the class in which it's used. For example:

this->idNum

Is referring to the idNum data of the class your writing for.

So to answer your question, yes you would only need the "this" keyword if your working with pointers because it is essentially a pointer. It's the pointer of a class pointing to itself, if that makes any sense to you.

Looks like you are using the words class and object interchangeably.

Correction:

The this pointer is a pointer accessible only within the nonstatic member functions of a class, struct, or union type. It points to the object for which the member function is called. Static member functions do not have a this pointer.

An object's this pointer is not part of the object itself; it is not reflected in the result of a sizeof statement on the object. Instead, when a nonstatic member function is called for an object, the address of the object is passed by the compiler as a hidden argument to the function.

lol, yeah. It's a bad habit of mine that I'm trying to get out of. I understand the difference (an object is an instance of a class), but for some reason I have momentary brain farts of something. :p

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.