#C++ Forward Referencing
13 messages in this thread
/*————————————————————————
Some C++ questions:
The attached code gives me the following error under Zortech C++ v2.06.
m11 = v1.x ;
^
"test.cpp", line 26 Syntax error: member 'x' of class 'Vector' is private
I have tried to get support from Zortech to no avail. Am I doing
something wrong in C++ or is it a compiler bug? I found that if I
re-order the file such that the Matrix class preceeds the Vector class,
the program compiles without a problem. I thought I had taken care of the
forward referencing, though. Is this a bug, or is it me?
Thanks, Bob Goldrich
———————————————————————–*/
class Vector ;
class Matrix ;
class Vector {
friend void Matrix::trans( const Vector& v1 ) ;
private:
int x ;
public:
Vector( int xx=0.0 ) ; //– constructor
} ;
class Matrix {
int m11 ;
public:
Matrix( int a11=0.0 ) ; //– constructor
void trans( const Vector& v1 ) ;
} ;
void Matrix::trans( const Vector& v1 )
{
m11 = v1.x ;
}
A forward reference to a class only allows you to declare a pointer or
reference to that class. The size of that class, and info about its
members is unknown at that time, thus your attempt to declare a member
function of the forward referenced class as a friend of the current class
is illegal. Zortechs fault is that it omits one error message. Cfront will
produce the following two error messages:
line 10: error: class Matrix undefined
line 26: error: Matrix::trans cannot access Vector::x: private
member
Reversing you declaration provides the Vector class with the info it needs
to allow the member function to be a friend, thus it works. With the
forward reference, you can make the entire Matrix class a friend, and then
the trans function will have access to Vector::x…
class Matrix;
class Vector {
friend Matrix;
private: …
Phil,
I found your answer in Lippman's book (p.179). I would have thought that
my friend declaration was ok, because all the line
friend void Matrix::trans( const Vector& v1 ) ;
says is "function 'trans' belonging to class 'Matrix' is granted access
to 'Vector's private members". No knowledge of Matrix is required other
than to give 'trans' access. That seems innocent enough, but I guess that's
the way it is. Doesn't seem right, somehow… -Bob
The way I understand it, there was a decision not to allow partial
definitions of a class, which is what you are doing when you declare a
member function of an as yet undefined class as a friend. I'm not a
compiler writer, but possibly this creates error checking problems if you
fail to declare that function as a member later, or you declare it
differently. If you fail to define a non-member function which you declare
a friend to a class, the linker gives you the error (if you attempt to use
the function). Whatever the reason, thats the way it is…
So, if you had 2 classes, each with a friend function which is also a
member of the other class, the only way to handle this is to make one
class a friend of the other? In such a situation it seems that the
forward references catch up with you, and you have no choice but to
make the entire class a friend. Right?…
Right. See quote from ARM in John Dlugosz message to you regarding same.
Thanks, Phil.
yup, that is a compiler bug. Looks like the 'friend' declaration only
sticks if the function already exists, or the declaration of trans in
Matrix somehow un-friends it. Wierd, but true. I'll forward this message
to Walter.
–John
John,
See Phil's message and my reply. It doesn't seem to be a bug, just a
'gotcha' of C++. Thanks for the help.
-Bob
nst Vector& v1 ) ;
says is "function 'trans' belonging to class 'Matrix' is granted access
to 'Vector's private members". No knowledge of Matrix is required other
than to give 'trans' access. That seems innocent enough, but I guess that's
the way it is. Doesn't seem right, somehow… -Bob
Yea, you're right. I had been thinking about the line in the DRM that
says, "If a function mentioned as a friend has not been declared its nam is
entered in the same scope as the name of the class containing the friend
declaration." which says nothing about only allowing non-member functions.
After posting that, I starting thinking about declarations for member
functions. That is, could you say Y::foo(); on a line somewhere? Unless
I could find a rule prohibiting it, why not? As far as I can tell it would
be useless though.
I looked in the new ARM and found that the commentary does state that,
"This implies that a friend daclaration may be the first mention of a class
or function name. However, there is no way of declaring a member function
earlier than its class. <example shown, similar to this case>. The only
way of specifying mutual friendship between two classes is to declare all
of the second class a friend ofthe [sic] first."
–John
What is this 'ARM'? Is it AT&T's C++ v2.0 spec? If so, I think its time I
got my hands on it. Perhaps Walter should add the second error/warning
message that Phil listed from cfront. That got me thinking, why, when a
language is standardized, don't they try to standardize compiler errors?
The DRM is the AT&T 2.0 spec. It is well worth getting ($20 I think). I
don't know the part number, but if you call AT&T you can find it. Also get
the "essential readings". All that comes with C++ compilers, except for
Zortech.
The ARM is the "annotated reference manual" which will be out from
Addison-Wesley in the summer. It is a replacement for The Book (The C++
Reference Manual), which is now in its 13th printing. It is a
specification of 2.1, with anotations added and commentary after each
chapter.
–John
Thanks John. -Bob