Few Questions:

Passing by values(copy of the value) or references(actual value)?
- What is the difference minus the two mentioned?
- What is the better choice?
- etc?

Also this is a more general quesiton OOP, with most languages its better to learn and use OOP then just programming a slab of code in the main. Gather the same for this?

Also quick refresh OOP = global variables, constructor, destructor and functions. The calls the functions to do the work (induces repitition the main objective of OOP), this correct?

Please correct, or fix up my mis conseptions.

Thanks in advance, Regards X

PS: Any other tips will be more than welcomed.

Recommended Answers

All 7 Replies

A lot of important questions here, so I will try and answer them the best I can.

First, the main difference between passing by value and passing by reference.. When we pass by value, the receiving function obtains a copy of the variable. If the function then alters the contents of that variable, these changes are not seen outside the function. This means the function has it's own local copy of the variable which does not affect anything outside of it.
When we pass by reference, we are passing a pointer or reference to an object, not a copy. This means when the function alters the object being referenced, the object is also changed outside of this function. Here is a quick example:

Passing by Value:

#include <iostream>
using namespace std;

int main() {
   int x = 5;
   cout << "In main before we call the function, x = " << x << endl; // result is 5
   MyFunction( x );
   cout << "In main after we call the function, x = " << x << endl; // result is still 5, even though we changed x inside MyFunction
   return 0;
}

void MyFunction( int x ) {
   cout << "In MyFunction x = " << x << endl; // result is 5 
   x = 10;
   cout << "In MyFunction x = " << x << endl; // result is now 10
}

If this does not fully make sense, then you should read about "scope" to really understand how all this works.


In general it is almost always best to use OOP approaches since it is easier to design, maintain, and implement in most cases - especially for large projects. Although you may not be coding large projects (thousands of lines of code), if you never practice it on small projects, trying to dive into OOP with a large project will be next to impossible. On the other hand, if you do not know much about coding to begin with, some find it easier to start with basic procedural programming first to understand the main structures such as variables, conditionals, loops, and functions, and then move on to OOP and learn about classes and so on.

The items you listed as being important to OOP are not really.... global variables and functions exist outside of OOP. The main concepts in OOP (although not all) are classes, inheritance, polymorphism, abstraction, and encapsulation. You may want to read about these terms... some of them may be confusing at first, and often people think "what's the point in encapsulation", but gradually this should make sense. For now though, I think the first step to understanding OOP is learning about the class.

A class, simply put, is a collection of related data along with methods that work on that data. Generally the data parts of a class are kept private to the class, meaning only methods inside the class can see and use the data. In order for some other class or function to "use" the data, the class has methods that are "public" that can be called from anywhere. These methods are often called the interface to the class.
Let's say you have a program that keeps track of student records. You could have a student class which stores all the grades of a student, a transcript of the courses the student has taken, the student's id number, etc. Now imagine a new student is enrolling at the school. You would first instantiate an instance of the student class - this is called an object. When an object is created, the constructor is called - perhaps in this case it will create a unique student ID for the student, insert their name, and set up an empty transcript record. Then imagine the student finishes a course. The program could then call a method of in the student class on that object called AddTranscriptRecord() which takes a class name and a mark and will update the student data. Now for the program to print the transcript we call the PrintTranscript() method in the student class.

This is just an example but hopefully it clarifies some things.

commented: Nice detailed explination, thankyou! +1

Oops I forgot to include a passing by reference example.. here it is:

#include <iostream>
using namespace std;

int main() {
   int x = 5;
   cout << "In main before calling function, x = " << x << endl; // result is 5
   MyFunction( &x ); // this time we send a pointer to x (passing by reference)
   cout << "In main after calling function, x = " << x << endl; // should be 10 now

   return 0;
}

void MyFunction( int* x ) { // accepts a pointer to x (reference)
   cout << "In MyFunction, x = " << x << endl; // result is 5
   *x = 10;
   cout << "In MyFunction, x = " << x << endl; // now it's 10
}

Be careful: it was not an example of passing by reference! It's passing a pointer by value.
The C and early C++ have no passing by reference at all. In modern C++ you may pass parameter by reference:

void byRef(int& x)
{
 ... x = 5;
}
...
int y = 0;
...
... byRef(y);
...

<< Be careful: it was not an example of passing by reference! It's passing a pointer by value.

I'll side with Mahlerfive on this one and see if debate follows or not. Passing an objcet by reference is different than passing a reference to an object. The concept of passing by reference includes both passing a pointer to an object and a reference to an of object as an argument (or parameter, I forget which is syntactically correct).

In C++ only passing a reference to an object semantically and syntactically corresponds to the common in programming languages term "passing by reference" (in use long before C++ was invented;)). Passing a pointer in C (and C++, of course) is only discomfort and awkward simulation of passing by reference (but sematically of value). Using *parameter notation gives evidence that another object was passed - a pointer to an object but not object himself. A reference is simply another name of an object. Feel the difference.

In C and C++ slang(s) a parameter lives in a function header, an argument - in a function call...

That's how matters stand.

Both answers are pretty much correct, depending on how you look at it. Passing a pointer to an object is considered passing by reference since the function now has a way to reference the object outside of itself. However, it is passing by value since you are really just passing the value of the pointer to the function, and that changing the value of the pointer itself will not affect anything outside the function.

What is the purpose of passing a pointer to a function though? The correct reason to do so would be to let the function see or alter the object that the pointer points to - which is the ultimate goal of passing by reference. It is on this point that I view passing a pointer as passing by reference over passing by value. I do find it important though that people understand both ways of thinking - however, for someone just learning the concept, I find that learning the REASON we do it first is most important.

Oh boy, there is a lot of wind being blown in this topic.

To simplify things, everything sent to a function gets copied (or generates an object) if--

-An implicit cast is done (sending an int to a function that takes an Integer object for example (and for further clarity, the Integer object has a constructor that isn't marked explicit and takes an int)) (non-pointer)
-You send a value of a built-in type to a function (non-pointer)
-You send a value of an object to a function (non-pointer)
-*You send a pointer to a function

* yes, a copy of the actual pointer is sent to the function, not the pointer itself.

To elaborate on the pointer issue, think about what a pointer's purpose is first. A pointer simply points to an address (with the restriction of the type of address the pointer can point to).

When you pass a pointer to a function, you are passing a copy of the pointer (so you're sending a copy-pointer to the function. It still references the same address though).

Alterations to the elements of the pointer will obviously effect the original version because the original version and the copy pointer point to the same address, so the de-referenced objects of both are the same.

However, if you change what the pointer is pointing to in the function, it changes what the copy is pointing to and not the initial pointer.

For example, if you were to assign NULL to a local parameter pointer in a function, it won't make the initial pointer point to 0 also, since the local parameter pointer is just a mere copy.

However, if your parameter is a reference to a pointer, you're sending the actual (NOT a copy, but the ACTUAL) pointer to the function and the assignment of NULL to that pointer will effect the original version since no copy was generated.

There are probably exceptions, but I wanted to point the pointer issue out specifically since it seemed that people weren't addressing it clearly. This caused some confusion for me when I started learning C++ until I found a post identical to what I just mentioned here.

If corrections are needed please let me know. This is what I understand about pointers sent to functions.

Note: You don't have this issue with regular references since a references denotes that you are passing the actual object as the parameter. Furthermore you cannot treat a regular reference like a pointer, but more-so like a constant pointer.

Example--

#include <iostream>

void alterValue(int*, int);
void falseAlterPointer(int*, int, const std::size_t);
void alterPointer(int*&, int, const std::size_t);
void printInfo(int*);

/**
 * Sending a copy of a pointer to this method and incrementing
 * a value derefenced by the copy by arg
 */
void alterValue(int *val, int arg){
    (*val) += arg; // altering value
}

/**
 * Attempts to alter the pointer, but fails since only the copy is altered.
 */
void falseAlterPointer(int *val, int newVal, const std::size_t size){
    val = new int[size];
    *val = newVal;
    printInfo(val);
    std::cout << "Warning! Copy pointer was changed, not original" << std::endl;
}

/**
 * This time, altering the actual pointer itself. No copy is sent to this method.
 */
void alterPointer(int *&val, int newVal, const std::size_t size){
    val = new int[size];
    *val = newVal;
    std::cout << "Original pointer was changed =)" << std::endl;
}

/**
 * Convenience method to reduce code repetition
 */
void printInfo(int *arg){
    std::cout << *arg << ", " << arg << std::endl;
}

int main(){

    int *tPtr = new int[1];
    *tPtr = 10;

    printInfo(tPtr); // displaying value and current address pointer points to
    alterValue(tPtr, 5); // incrementing the value by 5
    printInfo(tPtr); // displaying value and current address pointer points to
    falseAlterPointer(tPtr, 20, 3); // attempts to alter the pointer -- we'll see that it doesn't
    printInfo(tPtr); // proof here
    alterPointer(tPtr, 20, 3); // altering the actual pointer
    printInfo(tPtr); // result

    return 0;
}
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.