Passing a pointer by reference

Pages: 12
Hello,

I am currently working with this code for my operator overload and class definitions.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// CLASS DEFINITION FOR MainClass
class MainClass
{
private:
    int m_value1;
    const int m_value2;
    int* m_nPntr1;
    PieceClass1* m_advArray1;
public:
    MainClass(int arg_m_value = 0);
    ~MainClass();

    PieceClass1* GetAdvArray();
};


// CLASS DEFINITION FOR PieceClass1
class PieceClass1
{
public:
    int array1[5];
    PieceClass1(int startingValue = 0);
    friend ostream& operator<<(ostream&, const PieceClass1*&);
};

// DEFINITION OF GetAdvArray()
PieceClass1* MainClass::GetAdvArray()
{
    return this->m_advArray1;
}


// OPERATOR OVERLOAD
ostream& operator<<(ostream& output, const PieceClass1*& inputClass)
{
    for (int i = 0; i < 5; ++i)
    {
        output << inputClass->array1[i] << "\t";
    }
    return output;
}


The following code is my implementation of this class:

1
2
3
4
5
6
7
int main()
{
    MainClass compositionExample1(5);
    cout << compositionExample1.GetAdvArray() << "\n";

    return 0;
}


The problem with my code is that in my definition of my operator overload, the second parameter takes a reference to a pointer. However, it seems that when I try to pass the array, which is actually a pointer to an array, the operator overload never gets called and it prints the address of the pointer. Why is it not creating a reference to the pointer?

P.S. If I have the second parameter as just a pointer data type, then the operator overload gets called.
Last edited on
Most likely the problem is related to const-correctness. The operator overload requires a reference to a pointer to a const PieceClass1. But even before starting to talk about it, making it a pointer in the first place is incorrect. I know you think it is simpler for you to request that it takes a pointer, but in fact you are complicating yourself (clear proof is that your code isn't working).

Your operator<< must look like this:
ostream& operator<<(ostream &output, const PieceClass1 &inputClass);

See? No pointer. Just a reference to a const object. The const part is important if you access members of the class. You must only access them in a read-only way. If you call methods (directly or indirectly), those methods must be const or the underlying variables being changed must be mutable. The whole thing is not difficult, but yes, you have to know about const correctness.

1
2
3
4
5
6
7
ostream& operator<<(ostream &output, const PieceClass1 &inputClass)
{
    for(int i = 0; i < 5; ++i)
    {
        output << inputClass.array1[i] << "\t";
    }
}


And you modify the function GetAdvArray() to return a const reference of the object. The declaration changes to:

1
2
3
4
5
6
7
8
9
10
11
12
class MainClass
{
    ...
    const PieceClass1& GetAdvArray() const;
    ...
}

//And the definition:
const PieceClass1& MainClass::GetAdvArray() const
{
    return *m_advArray1;
}


That should simplify things for you. In general, don't use pointers to classes in your output/extraction operator overloads. It is an unnecessary nuisance.
I see what you are saying. However, I have asked this on another forum and received information that I am not technically having a pointer to a const object, but a const reference to a pointer to PieceClass1.

So pretty much, the real problem is having the const reference. When I changed the code to have a normal reference to a const pointer to a PieceClass1 instance, the code worked perfectly fine. This is the final implementation of the operator overload.

1
2
3
4
5
6
7
8
ostream& operator<<(ostream& output, PieceClass1* const & inputClass)
{
    for (int i = 0; i < 5; ++i)
    {
        output << inputClass->array1[i] << "\t";
    }
    return output;
}


I still have another question though (^_^). Why does having the const reference make it problematic?
All I can say is: Study about const correctness. Too long to explain in a single forum post.
Alright.

In the former code for my operator overload though, what is the second parameter directly translating too.

1
2
3
4
5
6
7
8
9
// OPERATOR OVERLOAD
ostream& operator<<(ostream& output, const PieceClass1*& inputClass)
{
    for (int i = 0; i < 5; ++i)
    {
        output << inputClass->array1[i] << "\t";
    }
    return output;
}


Does the parameter translate to a reference to a pointer, and the pointer points to a const instance of PieceClass1. Or does it mean a const reference to a pointer, which points to an instance of PieceClass1.

I have read that it is the latter, but is that correct?
Last edited on
A reference to a pointer to a constant PieceClass1.
Then is this a const reference to an instance of PieceClass1?

 
const PieceClass1& myInstance = X
That is a reference to a constant PieceClass1. What you seem to be missing is the fact that all references are constant (read-only). They can only be set on construction. After that they are immutable, so all references are const references.
Not according to this site.

http://www.learncpp.com/cpp-tutorial/611-references/

See the const reference section.
Last edited on
Where on that site does it say that you can make a reference refer to something else after initialization?
In fact:
Furthermore, the reference can not be “redirected” to another variable.


Edit: oh well, it also says:
You can assign const references to literal values

Whoever wrote this must have had a bad day.
Last edited on
Then according to that site, what is the syntax for a const reference and the syntax for a non-const reference to a const object of type PieceClass1? How do you differentiate the two? And what is the syntax to re-assign the reference once it has been set during construction, so it is not mistaken to be the class' operator= (assignment operator)?
Since a reference itself is always const (pointer) the expression "const reference" means a reference to a const object.
Okay, sorry about the confusion, never really thought about that the two were actually the same.

Anyway, why does not having a const pointer cause problems?
Because you cannot bind a temporary object (an rvalue) to a non-const reference.
This is a reference to a non-const pointer to const PieceClass1:
const PieceClass1*&
And this is a reference to a const pointer to (non-const) PieceClass1:
PieceClass1* const&

There is no need for a reference here anyway. Just drop it:
const PieceClass1* inputClass
And then you should probably drop the pointer and bring back the reference, as per webJose.

Just realized we're talking about operator<< here. Don't overload operator<< for pointer types.
The address being printed is the expected behavior.
Last edited on
Am I binding a temporary object to the pointer? I thought I was passing a pointer to an array to the parameter.
Last edited on
closed account (zb0S216C)
Flurite wrote:
"So pretty much, the real problem is having the const reference."

There's no such thing as a constant reference (it's nonsense) - only a reference to a constant T.

Wazzak
Last edited on
You're passing a pointer that was returned by a function. Values returned by functions are temporary objects and are destroyed at the end of the statement (or full-expression, technically).
Ahh, I see now. Never knew that ALL values returned were literals. It is probably similar for passing values as well.

Thanks to all!
They aren't literals. A literal is 5, 3.14 or "hello".
Also, while one could argue that there are no "constant references", there certainly are const references.
closed account (zb0S216C)
Athar wrote:
"Also, while one could argue that there are no "constant references", there certainly are const references."

Really? Could you be referring to the fact that compilers may implement references as constant pointers? If not, educate me :)

Wazzak
Pages: 12