Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > trouble assigning reference

Reply
Thread Tools

trouble assigning reference

 
 
Christopher
Guest
Posts: n/a
 
      05-07-2009
I am getting an odd compiler error:
'Pass:perator =' : cannot access private member declared in class
'Pass'

It is speaking as if I am trying to assign a Pass object to Pass
another object, but I am trying to assign a reference to another
reference.


//----------------------------------------------------------------------------
class Pass
{
public:

/** Only a Technique should construct a Pass */
friend class Technique;

~Pass();

// Snip

private:

/**
* Constructor
*
* Only a Technique should construct a Pass
**/
Pass(ID3D10EffectPass * pass);

/* No copy not allowed */
Pass(const Pass & rhs);

/** No assignment allowed */
Pass & operator = (const Pass & rhs);

// SNIP
};

class PolygonSet
{
// SNIP

protected:

// SNIP

struct PassInfo
{
PassInfo(Pass & pass, const std::vector<unsigned> &
vertexBufferIndices, ID3D10InputLayout * inputLayout);
PassInfo(const PassInfo & rhs);
PassInfo & operator = (const PassInfo & rhs);

Pass & m_pass; // A
single pass from a technique
std::vector<unsigned> m_vertexBufferIndices; // Which buffers
provide the data required for the pass
ID3D10InputLayout * m_inputLayout; // Input layout
used for a specific pass
};
};

//------------------------------------------------------------------------------------------
PolygonSet:assInfo & PolygonSet:assInfo:perator = (const
PassInfo & rhs)
{
m_pass =
rhs.m_pass; // PROBLEM HERE
m_vertexBufferIndices = rhs.m_vertexBufferIndices;
m_inputLayout = rhs.m_inputLayout;

return *this;
}



I don't understand why it is not letting me assign a reference to
another reference. I don't ever have problems doing that in a
constructor's initialization list. What's going on here?
 
Reply With Quote
 
 
 
 
joshuamaurice@gmail.com
Guest
Posts: n/a
 
      05-07-2009
On May 6, 5:29*pm, Christopher <(E-Mail Removed)> wrote:
> I am getting an odd compiler error:
> 'Pass:perator =' : cannot access private member declared in class
> 'Pass'

[snip]
> I don't understand why it is not letting me assign a reference to
> another reference. I don't ever have problems doing that in a
> constructor's initialization list. What's going on here?


References cannot be changed to point to something new after they're
created. Specifically, take the code fragment
int a;
int b;
int & ra = a;
int & rb = b;
ra = rb;
"ra = rb;" does not change reference ra to alias the object aliased by
rb. Instead, the references act like the objects being aliased. "ra =
rb;" takes the b object and assigns that to the a object.

If you want to change what a reference aliases, then you need
pointers.
 
Reply With Quote
 
 
 
 
Christopher
Guest
Posts: n/a
 
      05-07-2009
On May 6, 7:35*pm, (E-Mail Removed) wrote:
> References cannot be changed to point to something new after they're
> created. Specifically, take the code fragment
> * * int a;
> * * int b;
> * * int & ra = a;
> * * int & rb = b;
> * * ra = rb;
> "ra = rb;" does not change reference ra to alias the object aliased by
> rb. Instead, the references act like the objects being aliased. "ra =
> rb;" takes the b object and assigns that to the a object.
>
> If you want to change what a reference aliases, then you need
> pointers.


Crap. I hope I don't have to change the interfaces all the way down
the hierarchy.
Can I assign a pointer to point to an object, which a refereance
aliases?

I have a class "technique" that creates and manages the lifetime of
"pass" objects. I don't want anyone else constructing, deconstructing,
or changing the data of these pass objects, except the "technique"
that created it.

However, other classes need access to the information contained by the
"pass" class. So, I made a method in "technique" that returns a const
reference to a pass that it manages.

Now I have a "PassInfo" class that needs to be able to make calls and
access the info contained by a "pass", it doesn't need to change it,
but only access it. These "PassInfo" objects are stored in a
std::vector. So my problem is implementing the requirements of a class
that can be stored in the vector for "passinfo" without breaking the
rules for the "pass"

Phew, I hope that makes sense.



 
Reply With Quote
 
Neelesh
Guest
Posts: n/a
 
      05-07-2009
On May 7, 5:29*am, Christopher <(E-Mail Removed)> wrote:
> I am getting an odd compiler error:
> 'Pass:perator =' : cannot access private member declared in class
> 'Pass'
>
> It is speaking as if I am trying to assign a Pass object to Pass
> another object, but I am trying to assign a reference to another
> reference.
>


Reference is not something "different" than an object, a reference is
simply an alias (i.e. a different name) for an object. More
importantly, once an alias gets associated with an object, it cannot
get associated with any other object. Hence, assigning a reference is
effectively assigning the objects for which they are aliases.

> //-------------------------------------------------------------------------*---
> class Pass
> {
> public:
>
> * */** Only a Technique should construct a Pass */
> * *friend class Technique;
>
> * *~Pass();
>
> * *// Snip
>
> private:
>
> * */**
> * ** Constructor
> * **
> * ** Only a Technique should construct a Pass
> * ***/
> * *Pass(ID3D10EffectPass * pass);
>
> * */* No copy not allowed */
> * *Pass(const Pass & rhs);
>
> * */** No assignment allowed */
> * *Pass & operator = (const Pass & rhs);
>
> * *// SNIP
>
> };
>
> class PolygonSet
> {
> * // SNIP
>
> * protected:
>
> * // SNIP
>
> * struct PassInfo
> * {
> * * *PassInfo(Pass & pass, const std::vector<unsigned> &
> vertexBufferIndices, ID3D10InputLayout * inputLayout);
> * * *PassInfo(const PassInfo & rhs);
> * * *PassInfo & operator = (const PassInfo & rhs);
>
> * * *Pass & * * * * * * * * * * *m_pass; * * * * * * * * * * * // A
> single pass from a technique
> * * *std::vector<unsigned> m_vertexBufferIndices; * // Which buffers
> provide the data required for the pass
> * * *ID3D10InputLayout * * m_inputLayout; * * * * * * *// Input layout
> used for a specific pass
> * *};
>
> };
>
> //-------------------------------------------------------------------------*-----------------
> PolygonSet:assInfo & PolygonSet:assInfo:perator = (const
> PassInfo & rhs)
> {
> * *m_pass * * * * * * * * * * =
> rhs.m_pass; * * * * * * * * * * * * *// PROBLEM HERE
> * *m_vertexBufferIndices = rhs.m_vertexBufferIndices;
> * *m_inputLayout * * * * * = rhs.m_inputLayout;
>
> * *return *this;
>
> }
>
> I don't understand why it is not letting me assign a reference to
> another reference. I don't ever have problems doing that in a
> constructor's initialization list. What's going on here?


Because constructor initialization list is a place where, for the
first time, we give meaning to a reference. In other words, you tell
that reference whose alias it is. (Remember that there cannot be null
references, and hence every reference member must be explicitly
initialized in the constructor initialization list). Once that is
done, there is no way one can "separate out" the reference from the
object. Thus, any time other than a constructor initialization list,
any attempt to assign a reference effectively results in assigning
objects. References are not pointers.
 
Reply With Quote
 
Christopher
Guest
Posts: n/a
 
      05-07-2009
On May 6, 10:32*pm, Neelesh <(E-Mail Removed)> wrote:
> On May 7, 5:29*am, Christopher <(E-Mail Removed)> wrote:
>
> > I am getting an odd compiler error:
> > 'Pass:perator =' : cannot access private member declared in class
> > 'Pass'

>
> > It is speaking as if I am trying to assign a Pass object to Pass
> > another object, but I am trying to assign a reference to another
> > reference.

>
> Reference is not something "different" than an object, a reference is
> simply an alias (i.e. a different name) for an object. More
> importantly, once an alias gets associated with an object, it cannot
> get associated with any other object. Hence, assigning a reference is
> effectively assigning the objects for which they are aliases.
>
>
>
>
>
> > //-------------------------------------------------------------------------**---
> > class Pass
> > {
> > public:

>
> > * */** Only a Technique should construct a Pass */
> > * *friend class Technique;

>
> > * *~Pass();

>
> > * *// Snip

>
> > private:

>
> > * */**
> > * ** Constructor
> > * **
> > * ** Only a Technique should construct a Pass
> > * ***/
> > * *Pass(ID3D10EffectPass * pass);

>
> > * */* No copy not allowed */
> > * *Pass(const Pass & rhs);

>
> > * */** No assignment allowed */
> > * *Pass & operator = (const Pass & rhs);

>
> > * *// SNIP

>
> > };

>
> > class PolygonSet
> > {
> > * // SNIP

>
> > * protected:

>
> > * // SNIP

>
> > * struct PassInfo
> > * {
> > * * *PassInfo(Pass & pass, const std::vector<unsigned> &
> > vertexBufferIndices, ID3D10InputLayout * inputLayout);
> > * * *PassInfo(const PassInfo & rhs);
> > * * *PassInfo & operator = (const PassInfo & rhs);

>
> > * * *Pass & * * * * * * * * * * *m_pass; * * * * * * * * * * * // A
> > single pass from a technique
> > * * *std::vector<unsigned> m_vertexBufferIndices; * // Which buffers
> > provide the data required for the pass
> > * * *ID3D10InputLayout * * m_inputLayout; * * * * * * *// Input layout
> > used for a specific pass
> > * *};

>
> > };

>
> > //-------------------------------------------------------------------------**-----------------
> > PolygonSet:assInfo & PolygonSet:assInfo:perator = (const
> > PassInfo & rhs)
> > {
> > * *m_pass * * * * * * * * * * =
> > rhs.m_pass; * * * * * * * * * * * * *// PROBLEM HERE
> > * *m_vertexBufferIndices = rhs.m_vertexBufferIndices;
> > * *m_inputLayout * * * * * = rhs.m_inputLayout;

>
> > * *return *this;

>
> > }

>
> > I don't understand why it is not letting me assign a reference to
> > another reference. I don't ever have problems doing that in a
> > constructor's initialization list. What's going on here?

>
> Because constructor initialization list is a place where, for the
> first time, we give meaning to a reference. In other words, you tell
> that reference whose alias it is. (Remember that there cannot be null
> references, and hence every reference member must be explicitly
> initialized in the constructor initialization list). Once that is
> done, there is no way one can "separate out" the reference from the
> object. Thus, any time other than a constructor initialization list,
> any attempt to assign a reference effectively results in assigning
> objects. References are not pointers.- Hide quoted text -
>
> - Show quoted text -


Ok, I think I understand the problem.
Two more questions though:

1) I think I can have a null reference. What can i expect when this
happens:

#include <iostream>

int main()
{
int * ptr = new int(7);
int & ref = *ptr;
delete ptr;

// more stuff

std::cout << ref << std::endl;
}

2) Is this safe?

#include <iostream>

class A
{
public:

A() { m_ptr = new int(9); }
~A() { delete m_ptr; }

const int & GetInt() const { return *m_ptr; }

private:

int * m_ptr;
};

int main()
{
A a();
int * anotherPtr = &(a.GetInt());

std::cout << *anotherPtr << std::endl;

return 0;
}

 
Reply With Quote
 
Neelesh
Guest
Posts: n/a
 
      05-07-2009
On May 7, 5:50*am, Christopher <(E-Mail Removed)> wrote:
> On May 6, 7:35*pm, (E-Mail Removed) wrote:
>
> > References cannot be changed to point to something new after they're
> > created. Specifically, take the code fragment
> > * * int a;
> > * * int b;
> > * * int & ra = a;
> > * * int & rb = b;
> > * * ra = rb;
> > "ra = rb;" does not change reference ra to alias the object aliased by
> > rb. Instead, the references act like the objects being aliased. "ra =
> > rb;" takes the b object and assigns that to the a object.

>
> > If you want to change what a reference aliases, then you need
> > pointers.

>
> Crap. I hope I don't have to change the interfaces all the way down
> the hierarchy.
> Can I assign a pointer to point to an object, which a refereance
> aliases?
>


Yes.

int a;
int &b = a;
int *c = &b; //Same as int* c = &a;

> I have a class "technique" that creates and manages the lifetime of
> "pass" objects. I don't want anyone else constructing, deconstructing,
> or changing the data of these pass objects, except the "technique"
> that created it.
>
> However, other classes need access to the information contained by the
> "pass" class. So, I made a method in "technique" that returns a const
> reference to a pass that it manages.
>
> Now I have a "PassInfo" class that needs to be able to make calls and
> access the info contained by a "pass", it doesn't need to change it,
> but only access it. These "PassInfo" objects are stored in a
> std::vector. So my problem is implementing the requirements of a class
> that can be stored in the vector for "passinfo" without breaking the
> rules for the "pass"
>


Instead of having a Pass& in the struct PassInfo, use a pointer-to-
const. A (non-const)pointer can point to a different object, and a
pointer-to-const will make sure that you donot use that pointer to
change the "Pass" object that it points to, since you essentially
donot want the PassInfo object to change the Pass object associated
with it.

You may find these useful:
http://www.parashift.com/c++-faq-lit...s.html#faq-8.2 : About
"assiging a reference"
http://www.parashift.com/c++-faq-lit...s.html#faq-8.6 : About
"pointers vs. references".




 
Reply With Quote
 
Neelesh
Guest
Posts: n/a
 
      05-07-2009
On May 7, 8:47*am, Christopher <(E-Mail Removed)> wrote:
>
>
> Two more questions though:
>
> 1) I think I can have a null reference.


No. The C++ standard clearly says that "null reference cannot exist in
a well-defined program" (8.3.2p4)
Note that a reference can never be null, it can refer to a pointer
that can be null.

>What can i expect when this
> happens:
>
> #include <iostream>
>
> int main()
> {
> * *int * ptr = new int(7);
> * *int & ref = *ptr;
> * *delete ptr;
>
> * *// more stuff
>
> * *std::cout << ref << std::endl;
>
> }
>


This is an undefined behaviour, since you are trying to dereference
the pointer ptr after deleting it.

> 2) Is this safe?
>


> #include <iostream>
>
> class A
> {
> public:
>
> * *A() { m_ptr = new int(9); }
> * *~A() { delete m_ptr; }
>
> * *const int & GetInt() const { return *m_ptr; }
>
> private:
>
> * *int * m_ptr;
>
> };
>
> int main()
> {
> * *A a();


Beware - You think you are defining an object of type A using the 0-
arg constructor, but the compiler thinks something totally different.
The compiler treats this as a function declaraction for a function a
that takes nothing and returns a.

If you want to declare a variable representing an object of type a,
simply say
A a;

> * *int * anotherPtr = &(a.GetInt());


This line gives error since a is a treated as a function by the
compiler and there is no way it can have GetInt member function.
Changing A a() to A a will remove this error, but still there is one
more error. Observe that GetInt function returns a reference to a
const-int. Hence, &(a.GetInt()) has type "pointer-to-const". A pointer-
to-const cannot be assigned to a pointer-to-non-const. You will need
to change int * anotherPtr to const int* anotherPtr to make this line
compile.

>
> * *std::cout << *anotherPtr << std::endl;
>
> * *return 0;
>
> }


Finally, it is OK to have anotherPtr as long as you donot delete
anotherPtr or try to dereference it after the object "a" ceases to
exist. But this kind of usage might unknowingly lead you in trouble,
specifically if you aren't sure what all places is this pointer being
used.

Thanks.
 
Reply With Quote
 
Neelesh
Guest
Posts: n/a
 
      05-07-2009
Typo correction:
On May 7, 9:24*am, Neelesh <(E-Mail Removed)> wrote:
> > 2) Is this safe?

>
> > #include <iostream>

>
> > class A
> > {
> > public:

>
> > * *A() { m_ptr = new int(9); }
> > * *~A() { delete m_ptr; }

>
> > * *const int & GetInt() const { return *m_ptr; }

>
> > private:

>
> > * *int * m_ptr;

>
> > };

>
> > int main()
> > {
> > * *A a();

>


Beware - You think you are defining an object of type A using the 0-
arg constructor, but the compiler thinks something totally different.
The compiler treats this as a function declaraction for a function a
that takes nothing and returns *an object of type A by value*.

> [...]

 
Reply With Quote
 
Vladimir Jovic
Guest
Posts: n/a
 
      05-07-2009
Neelesh wrote:
> On May 7, 8:47 am, Christopher <(E-Mail Removed)> wrote:
>>
>> Two more questions though:
>>
>> 1) I think I can have a null reference.

>
> No. The C++ standard clearly says that "null reference cannot exist in
> a well-defined program" (8.3.2p4)
> Note that a reference can never be null, it can refer to a pointer
> that can be null.


1)

int *a=NULL;
int &b = *a;

2)

int *a = NULL;
int *&b = a;


Which one you had on your mind here?
The 1) causes an undefined behaviour.

 
Reply With Quote
 
Neelesh
Guest
Posts: n/a
 
      05-07-2009
On May 7, 3:44*pm, Vladimir Jovic <(E-Mail Removed)> wrote:
> Neelesh wrote:
> > On May 7, 8:47 am, Christopher <(E-Mail Removed)> wrote:

>
> >> Two more questions though:

>
> >> 1) I think I can have a null reference.

>
> > No. The C++ standard clearly says that "null reference cannot exist in
> > a well-defined program" (8.3.2p4)
> > Note that a reference can never be null, it can refer to a pointer
> > that can be null.

>
> 1)
>
> int *a=NULL;
> int &b = *a;
>


a is a null pointer, b is a reference to an integer. Since b is
initialized by dereferncing a null pointer, it is undefined what value
would b have. Therefore the program also has undefined behavior.

> 2)
>
> int *a = NULL;
> int *&b = a;
>


a is a null pointer, b is a reference to an integer pointer, and b is
initialized as a null pointer. In other words, b is a "valid"
reference to a "null pointer". But that doesnot make b a "null
reference".

> Which one you had on your mind here?
> The 1) causes an undefined behaviour.


In neither of the two cases, "the reference is null". In fact, a
reference can never be "null".
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Assigning methods to objects, and assigning onreadystatechange to an XMLHttpRequest -- an inconsistency? weston Javascript 1 09-22-2006 09:33 AM
assigning reference to a returned value from function. ypjofficial@indiatimes.com C++ 12 08-10-2006 06:33 AM
Assigning the address returned from new to a reference Protoman C++ 14 11-27-2005 08:22 AM
Assigning to a reference Dave C++ 5 11-06-2003 07:17 PM
Assigning reference to variables.. fAbs C++ 17 10-02-2003 06:01 PM



Advertisments