Questions!

1.Does a const data member have to be initialized in the constructor/initialization list?

2.And where are static const data members defined (get a value)?

3.Function parameters behave like local variables inside the function, right? Can parameters passed by value be changed? I never saw a function that changes parameter variables passed by value. I can save memory. For example, is the following code legal in C++?
int Increase(int a)
{
a++;
return a;
}

In other words, can a be changed and used like a local variable, let's say, after I don't need its original value anymore?


1. Yes
2. Didn't you already open a topic on that?
3. Yes:
1
2
3
4
5
6
7
8
9
10
11
int Increase(int a)
{
     a++;
     return a;
}
int main()
{
     int x=1, y;
     y = Increase(x); // y==2, x==1
     y = Increase(3); // y==4
}
If a can be changed, why do programmers not use the parameter variables? For example, if you have a vector class, the operator+ function doesn't need to create a temporary vector (I saw at least one example in the tutorial in which a parameter is not used even though there was no reason not to use it to save few bytes...) ! It can get to vector by value, add the first to the second and return the second by value! Instead, in examples a temporary vector is used. Why?
Who says they don't?

Can you post a link to the example?

EDIT: Okay, I think I found it. You mean this one?
1
2
3
4
5
6
CVector CVector::operator+ (CVector param) {
  CVector temp;
  temp.x = x + param.x;
  temp.y = y + param.y;
  return (temp);
}

You're right, there's no reason not to use the copied object, but that's not what the example was about, so it's irrelevant. The method correctly coded would have been:
1
2
3
4
5
6
CVector *CVector::operator+ (CVector &param){
	CVector *res=new CVector(param);
	res->x+=this->x;
	res->y+=this->y;
	return res;
}

but that doesn't demonstrate operator overloading any more than the first example.
Last edited on
@Tom Backton

hmm I'm not sure what you're trying to say, maybe some code examples would be understood much better. I think what you're trying to say though is that pass by value parameters get changed? Actually pass by value parameters don't get changed since their scope is only within the function. Well for example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// example of wrong thing to do
#include <iostream>
#include <limits>

void doubleIt(int num)
{
     num = num * 2;
}

int main()
{
    int myNum = 2;
    
    doubleIt(myNum);       // pass by value WRONG doesn't double myNum

    std::cout << myNum << std::endl;   // prints out 2
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    return 0;
}


It would print out 2 on your console. Why? Since the parameter is actually a local variable and it's scope is only within the function.

When you pass something in by value the function actually makes a copy. This copy isn't the variable you passed into the function but a new variable.
The copy is what the function does it's operations on.
when the function ends all the variables or parameters inside the function is freed up automatically. Hence the copy would be freed up and everything you did with it would be gone as well.

One way around this, is to return the value of the copy variable back to the original variable just like Bazzy shown in his code. So in our example we could fix it by making a few changes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//solution using return  
#include <iostream>
#include <limits>

int doubleIt(int num)
{
     return num * 2;
}

int main()
{
    int myNum = 2;
    
    myNum = doubleIt(myNum);   // pass by value returns result to original

    std::cout << myNum << std::endl;   // prints out 4
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    return 0;
}


Now the program would print out 4 which is the correct value. However, remember the thing about the copy variable? We had to make a copy which means that instead of just having one integer variable to operate on we needed 2 integer variables. This may be ok since integers take up only a few bytes of memory. It's pretty inefficient when you're working with classes or structures that take up more memory. Which brings us to another solution.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// pass by reference
// The C  solution using pointers
#include <iostream>
#include <limits>

void doubleIt(int *num)
{
     *num = (*num) * 2;
}

int main()
{
    int myNum = 2;
    
    doubleIt(&myNum);     // C-style pass by reference also works in C++

    std::cout << myNum << std::endl;   // prints out 4
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    return 0;
}


And the C++ way of passing by reference

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// pass by reference
// The C++ solution using references
#include <iostream>
#include <limits>

void doubleIt(int &num)
{
     num = num * 2;
}

int main()
{
    int myNum = 2;
    
    doubleIt(myNum);     // C++ style pass by reference

    std::cout << myNum << std::endl;   // prints out 4
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    return 0;
}


the main advantage of passing by reference is it doesn't make a copy variable, saving you a few bytes. When you pass by value on the other hand, you can never save a few bytes because of the copy variable. I hope that made it clearer.
Last edited on
I already know all this...but helios gave me the answer I needed. Thanks.

@helios : I meant the example could be replaced with this:

1
2
3
4
5
CVector CVector::operator+ (CVector param) {
  param.x+=x;
  param.y+=y;
  return param;
}
Last edited on
Yes, but typically if the copy of the object is expensive, the preferred solution is to pass by const reference. Pass by value only when a) copying the object is inexpensive and b) the called function must not modify the callee's variable.

Actually helios' modification to CVector is bad and wrong since it changes the interface; the original is better, and Tom's code above is probably best (except that operator+ should be a const member function).

There is no speed difference between

1
2
3
4
5
6
CVector CVector::operator+( const CVector& rhs ) const {
    CVector temp( rhs );
    tmp.x += x; 
    tmp.y += y;
    return temp;
}


and

1
2
3
4
5
CVector CVector::operator+( CVector rhs ) const {
    rhs.x += x;
    rhs.y += y;
    return rhs;
}    


because in the former case an explicit copy of the source vector is done and in the latter case the compiler does an implicit copy of the source vector to the stack.
Thanks for the help :)
Topic archived. No new replies allowed.