By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,670 Members | 1,526 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,670 IT Pros & Developers. It's quick & easy.

I don't know what's wrong with my very simple code

P: n/a
Sam
Hi I'm learning to code with C++ and wrote some very simple code. I
think it's consistent with every rule but always got compiling errors
that I don't understand.

The code include 5 files as following, delimited by //////:

////////////////pose.h
#ifndef pose_h
#define pose_h
#include "point.h"
class pose
{
int i;
public:
friend void point::init(pose P);
};
#endif

////////////////pose.cpp
#include "pose.h"

////////////////point.h
#ifndef point_h
#define point_h
#include "pose.h"
class point
{
public:
void init(pose P);
};
#endif

////////////////point.cpp
#include "point.h"
void point::init(pose P)
{
P.i=1;
}

////////////////main.cpp
#include "pose.h"
#include "point.h"
void main()
{
}
Basically the "point" class has a function to modify the "pose"
object's private data "i". VC++ always gives the error messages like:
'point' : is not a class or namespace name
'i' : cannot access private member declared in class 'pose'
syntax error : identifier 'pose'
nonexistent function 'point::init' specified as friend

I cannot understand it. Could anybody tell me what he thinks of it?
Thanks a lot.
Jul 22 '05 #1
Share this Question
Share on Google+
20 Replies


P: n/a
Sam writes:
Hi I'm learning to code with C++ and wrote some very simple code. I
think it's consistent with every rule but always got compiling errors
that I don't understand.

The code include 5 files as following, delimited by //////:

////////////////pose.h
#ifndef pose_h
#define pose_h
#include "point.h"
class pose
{
int i;
i is, by default private. Which is what the compiler told you. Good
practice says it *should be* private. Use a friend class/function or use an
accessor to fiddle with the value of i. For a real program you should
probably rethink your overall design.

You are on the verge of developing some bad habits.
public:
friend void point::init(pose P);
};
#endif

////////////////pose.cpp
#include "pose.h"

////////////////point.h
#ifndef point_h
#define point_h
#include "pose.h"
class point
{
public:
void init(pose P);
};
#endif

////////////////point.cpp
#include "point.h"
void point::init(pose P)
P.i=1;
}

////////////////main.cpp
#include "pose.h"
#include "point.h"
void main()
{
}
Basically the "point" class has a function to modify the "pose"
object's private data "i". VC++ always gives the error messages like:
'point' : is not a class or namespace name
'i' : cannot access private member declared in class 'pose'
syntax error : identifier 'pose'
nonexistent function 'point::init' specified as friend


Jul 22 '05 #2

P: n/a
A friend function can not be a member of a class. So point::init can not be
a friend to pose.

Jakob

"Sam" <hc***@nd.edu> wrote in message
news:f0*************************@posting.google.co m...
Hi I'm learning to code with C++ and wrote some very simple code. I
think it's consistent with every rule but always got compiling errors
that I don't understand.

The code include 5 files as following, delimited by //////:

////////////////pose.h
#ifndef pose_h
#define pose_h
#include "point.h"
class pose
{
int i;
public:
friend void point::init(pose P);
};
#endif

////////////////pose.cpp
#include "pose.h"

////////////////point.h
#ifndef point_h
#define point_h
#include "pose.h"
class point
{
public:
void init(pose P);
};
#endif

////////////////point.cpp
#include "point.h"
void point::init(pose P)
{
P.i=1;
}

////////////////main.cpp
#include "pose.h"
#include "point.h"
void main()
{
}
Basically the "point" class has a function to modify the "pose"
object's private data "i". VC++ always gives the error messages like:
'point' : is not a class or namespace name
'i' : cannot access private member declared in class 'pose'
syntax error : identifier 'pose'
nonexistent function 'point::init' specified as friend

I cannot understand it. Could anybody tell me what he thinks of it?
Thanks a lot.

Jul 22 '05 #3

P: n/a
osmium wrote:
Sam writes:

Hi I'm learning to code with C++ and wrote some very simple code. I
think it's consistent with every rule but always got compiling errors
that I don't understand.

The code include 5 files as following, delimited by //////:

////////////////pose.h
#ifndef pose_h
#define pose_h
#include "point.h"
class pose
{
int i;

i is, by default private. Which is what the compiler told you. Good
practice says it *should be* private. Use a friend class/function or use an
accessor to fiddle with the value of i. For a real program you should
probably rethink your overall design.

You are on the verge of developing some bad habits.

The design issue aside, the OP's question is about why the friend
declaration doesn't work as he thinks it should. He knows that i is
private, and he did have a friend function declared.

To the OP, you could get around your problem by using a combination of a
reference parameter and a forward declaration:

////////////////////////////////////////////////////////////////////////////
// A.hpp
#ifndef A_HPP_INCLUDED
#define A_HPP_INCLUDED

#include "B.hpp"

class A
{
/* ... */
friend void B:f(A& a); // A forward declaration does not suffice
// here; you must have the full definition
// of B, hence the #include above.
/* ... */
};

#endif // include guard

////////////////////////////////////////////////////////////////////////////
// B.hpp
#ifndef B_HPP_INCLUDED
#define B_HPP_INCLUDED

class A; // forward declaration

class B
{
/* ... */
public:
void f(A& a); // Note that for a reference or pointer
// to A, you only need the forward
// declaration, not the full class
// definition.

/* ... */
};
The reason what you tried earlier didn't work is that your include
directives would have resulted in a circular dependency, which your
include guard prevented. (That's what include guards are for, after all.)

If you can't use a reference parameter, then you will have to try
something else -- like a public accessor method in class A. However,
you should prefer to pass classes by reference in most situations, as
passing by value invokes the class' copy constructor. Note that in that
case, the function would only modify a copy of the parameter anyway,
which is almost certainly not what you want.

HTH,

- Adam

--
Reverse domain name to reply.

Jul 22 '05 #4

P: n/a

"Sam" <hc***@nd.edu> wrote in message
news:f0*************************@posting.google.co m...
Hi I'm learning to code with C++ and wrote some very simple code. I
think it's consistent with every rule but always got compiling errors
that I don't understand.

The code include 5 files as following, delimited by //////:

////////////////pose.h
#ifndef pose_h
#define pose_h
#include "point.h"
class pose
{
int i;
public:
friend void point::init(pose P);
};
#endif

////////////////pose.cpp
#include "pose.h"

////////////////point.h
#ifndef point_h
#define point_h
#include "pose.h"
class point
{
public:
void init(pose P);
};
#endif

////////////////point.cpp
#include "point.h"
void point::init(pose P)
{
P.i=1;
}

////////////////main.cpp
#include "pose.h"
#include "point.h"
void main()
{
}
Basically the "point" class has a function to modify the "pose"
object's private data "i". VC++ always gives the error messages like:
'point' : is not a class or namespace name
'i' : cannot access private member declared in class 'pose'
syntax error : identifier 'pose'
nonexistent function 'point::init' specified as friend

I cannot understand it. Could anybody tell me what he thinks of it?
Thanks a lot.


//////////////// pose.h
#ifndef pose_h
#define pose_h

#include "point.h"
class pose {
int i;
friend void point::init (pose &P);
};

#endif

//////////////// point.h
#ifndef point_h
#define point_h

class pose;

class point {
public:
void init (pose &);
};

#endif

//////////////// pose.cpp
#include "pose.h"

//////////////// point.cpp

#include "point.h"
#include "pose.h"

void point::init (pose &P) {
P.i = 1;
}

//////////////// main.cpp

#include "pose.h"
#include "point.h"
int main () {
pose p;
point pt;
pt.init (p);
}

I think you mean to pass the 'pose' by reference? As others have mentioned,
there are probably better ways of achieving your goal here.

Regards

Brian


Jul 22 '05 #5

P: n/a

"Jakob B. Olsen" <ja***********@hotmail.com> wrote in message
news:3f**********************@dread14.news.tele.dk ...
A friend function can not be a member of a class. So point::init can not be a friend to pose.


This is total nonesense.
Jul 22 '05 #6

P: n/a
Sam
"Jakob B. Olsen" <ja***********@hotmail.com> wrote in message news:<3f**********************@dread14.news.tele.d k>...
A friend function can not be a member of a class. So point::init can not be
a friend to pose.

Jakob

I checked it out from the book "thinking in c++" finding that a friend
fn can be a member of a class.

Now I think the problem might be, whichever class is compiled first,
it needs the info of the the other class. When it goes to the other
class, it finds that it needs the previous class. That's the way I
understand it because I switched the order of compiling classes but
always found the compiler thinks the class (or class member fn) is not
defined.

Sam
"Sam" <hc***@nd.edu> wrote in message
news:f0*************************@posting.google.co m...
Hi I'm learning to code with C++ and wrote some very simple code. I
think it's consistent with every rule but always got compiling errors
that I don't understand.

The code include 5 files as following, delimited by //////:

////////////////pose.h
#ifndef pose_h
#define pose_h
#include "point.h"
class pose
{
int i;
public:
friend void point::init(pose P);
};
#endif

////////////////pose.cpp
#include "pose.h"

////////////////point.h
#ifndef point_h
#define point_h
#include "pose.h"
class point
{
public:
void init(pose P);
};
#endif

////////////////point.cpp
#include "point.h"
void point::init(pose P)
{
P.i=1;
}

////////////////main.cpp
#include "pose.h"
#include "point.h"
void main()
{
}
Basically the "point" class has a function to modify the "pose"
object's private data "i". VC++ always gives the error messages like:
'point' : is not a class or namespace name
'i' : cannot access private member declared in class 'pose'
syntax error : identifier 'pose'
nonexistent function 'point::init' specified as friend

I cannot understand it. Could anybody tell me what he thinks of it?
Thanks a lot.

Jul 22 '05 #7

P: n/a
In file point.cpp, the first line of code is:

#include "point.h"

Try changing it to:

#include "pose.h"
Jul 22 '05 #8

P: n/a
On 6 Jan 2004 06:41:20 -0800, hc***@nd.edu (Sam) wrote:
Hi I'm learning to code with C++ and wrote some very simple code. I
think it's consistent with every rule but always got compiling errors
that I don't understand.

The code include 5 files as following, delimited by //////:

////////////////pose.h
#ifndef pose_h
#define pose_h
#include "point.h"
class pose
{
int i;
public:
friend void point::init(pose P);
};
#endif

////////////////pose.cpp
#include "pose.h"

////////////////point.h
#ifndef point_h
#define point_h
#include "pose.h"
The above line shouldn't be there - it introduces a circular
dependency (pose.h depends on point.h which in turn depends on pose.h
and so on). Instead, just use a forward declaration:
class pose;
class point
{
public:
void init(pose P);
I think you intended to pass by reference:

void init(pose& P);
};
#endif

////////////////point.cpp
#include "point.h"
and here you now need:
#include "pose.h" //need complete definition of pose.
void point::init(pose P)
{
P.i=1;
}

////////////////main.cpp
#include "pose.h"
#include "point.h"
void main()
{
}


Tom

C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Jul 22 '05 #9

P: n/a
#ifndef point_h
#define point_h

#include "pose.h"

class pose; // <--------- ADD THIS forward decleration

class point
{
public:
void init(pose P);
};

#endif
Jul 22 '05 #10

P: n/a
Sam
tom_usenet <to********@hotmail.com> wrote in message news:<pl********************************@4ax.com>. ..
On 6 Jan 2004 06:41:20 -0800, hc***@nd.edu (Sam) wrote:
Hi I'm learning to code with C++ and wrote some very simple code. I
think it's consistent with every rule but always got compiling errors
that I don't understand.

The code include 5 files as following, delimited by //////:

////////////////pose.h
#ifndef pose_h
#define pose_h
#include "point.h"
class pose
{
int i;
public:
friend void point::init(pose P);
};
#endif

////////////////pose.cpp
#include "pose.h"

////////////////point.h
#ifndef point_h
#define point_h
#include "pose.h"


The above line shouldn't be there - it introduces a circular
dependency (pose.h depends on point.h which in turn depends on pose.h
and so on). Instead, just use a forward declaration:
class pose;


Thank you Tom. I tried it. You're right and you got the problem - a
circular dependency.
A forward declaration "class pose" should appear in point.h, and then
"#include pose.h" should be in point.cpp so the circular dependency is
avoided.
class point
{
public:
void init(pose P);


I think you intended to pass by reference:

void init(pose& P);


I don't understand why everyone wants to pass by reference. Why not
just pass by object. It works.
};
#endif

////////////////point.cpp
#include "point.h"


and here you now need:
#include "pose.h" //need complete definition of pose.
void point::init(pose P)
{
P.i=1;
}

////////////////main.cpp
#include "pose.h"
#include "point.h"
void main()
{
}


Tom

C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html

Jul 22 '05 #11

P: n/a
On 7 Jan 2004 06:30:47 -0800, hc***@nd.edu (Sam) wrote:
>class point
>{
>public:
> void init(pose P);


I think you intended to pass by reference:

void init(pose& P);


I don't understand why everyone wants to pass by reference. Why not
just pass by object. It works.


Let's take a look at the definition of init:
>void point::init(pose P)
>{
>P.i=1;
>}


init seems to want to assign 1 to P.i. If P is passed by value, the
change will be made to a local copy of P, and the pose from the call
site will be unmodified. In other words, the function as written is a
no-op. Read up on pass-by-reference vs. pass-by-value. There should be
some FAQs about it (see my sig).

Tom

C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Jul 22 '05 #12

P: n/a
Sam
tom_usenet <to********@hotmail.com> wrote in message news:<pl********************************@4ax.com>. ..
On 6 Jan 2004 06:41:20 -0800, hc***@nd.edu (Sam) wrote:
Hi I'm learning to code with C++ and wrote some very simple code. I
think it's consistent with every rule but always got compiling errors
that I don't understand.

The code include 5 files as following, delimited by //////:

////////////////pose.h
#ifndef pose_h
#define pose_h
#include "point.h"
class pose
{
int i;
public:
friend void point::init(pose P);
};
#endif

////////////////pose.cpp
#include "pose.h"

////////////////point.h
#ifndef point_h
#define point_h
#include "pose.h"


The above line shouldn't be there - it introduces a circular
dependency (pose.h depends on point.h which in turn depends on pose.h
and so on). Instead, just use a forward declaration:
class pose;
class point
{
public:
void init(pose P);


I think you intended to pass by reference:

void init(pose& P);

I just want to make it clearer. Here the fn init(pose P) is a friend
of pose, so it can modify P's private values. It does not have to use
reference to modify P's private values.
};
#endif

////////////////point.cpp
#include "point.h"


and here you now need:
#include "pose.h" //need complete definition of pose.
void point::init(pose P)
{
P.i=1;
}

////////////////main.cpp
#include "pose.h"
#include "point.h"
void main()
{
}


Tom

C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html

Jul 22 '05 #13

P: n/a
On 7 Jan 2004 06:39:55 -0800, hc***@nd.edu (Sam) wrote:
I think you intended to pass by reference:

void init(pose& P);

I just want to make it clearer. Here the fn init(pose P) is a friend
of pose, so it can modify P's private values. It does not have to use
reference to modify P's private values.


Yes it does. If you pass by value you are modifying private values of
a copy of the passed pose object, not the original object.

Tom

C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Jul 22 '05 #14

P: n/a
On Wed, 07 Jan 2004 10:51:26 +0000, dwizard wrote:
#ifndef point_h
#define point_h

#include "pose.h"

class pose; // <--------- ADD THIS forward decleration

class point
{
public:
void init(pose P);
};

#endif


Won't work. Needs a complete definition of the class to pass to init, a
forward declaration will not do.

HTH,
M4

Jul 22 '05 #15

P: n/a
Martijn Lievaart wrote:
On Wed, 07 Jan 2004 10:51:26 +0000, dwizard wrote:

#ifndef point_h
#define point_h

#include "pose.h"

class pose; // <--------- ADD THIS forward decleration

class point
{
public:
void init(pose P);
};

#endif

Won't work. Needs a complete definition of the class to pass to init, a
forward declaration will not do.

HTH,
M4

Besides that, once you've included the header that provides a full
declaration of a class, providing a forward declaration of that class
afterwards does absolutely nothing.

- Adam

--
Reverse domain name to reply.

Jul 22 '05 #16

P: n/a
Sam wrote:
class point
{
public:
void init(pose P);


I think you intended to pass by reference:

void init(pose& P);

I just want to make it clearer. Here the fn init(pose P) is a friend
of pose, so it can modify P's private values. It does not have to use
reference to modify P's private values.


Right.
But that init function is called from somewhere. Eg.

int main()
{
point A;
pose B;

A.init( B );

Well. As you have written it now, a copy of B is made and given to init().
init() now modifes this copy. But this also means that B is never touched
and modified. In some situations this is indeed what someone wants to
achieve, but most of the time it is not. More often you want the function
to change the object given to it. In this case you have to use a reference.

Also: make it a habit of yours to pass class objects by reference.
If you want the function to able to change the callers object, you
use an ordinary reference:

void point::init( pose& Arg )
{
Arg.i = 2;
}

If you don't want the function to be able to change the callers argument,
you pass by const reference:

void point::init( const pose& Arg )
{
Arg.i = 2;
}

Now the compiler will emit an error, saying that i of Arg cannot be changed,
since you promised that it is const - non changable.

The reason why you want to pass a reference is, that when you pass by value

void point::init( pose Arg )

a copy of the callers pose object is made. Depending on the object itself this
can be a (very) costly operation. Well in your case the pose object seems to
be simple enough that this would not be a problem, but there is more to it:
The pass by reference doesn't cost you much more then creating a copy of the
object, so it doesn't really matter which one you choose (in this example). Therefore
you are in the situation: in the worst case, both passing mechanisms are cost equal
but in the best case the pass by reference saves you from a costly operation. So use
pass by reference and be on the safe side at all times.

The only exception is: If you definitly don't want to change the callers argument,
but yet have to work with that object and change it locally in that function, you can
use a pass by value. But even then it is arguable if one should pass per const reference
and create the copy explicitely to document the feature that you know what you are
doing and you know that the change is not reflected to the caller of that function:

void point::init( const pose& Arg )
{
pose ArgCopy( Arg ); // creating a copy of what the caller passed

ArgCopy.i = 3; // I know that the assignment takes place at a
// copy of whatever the caller has passed to this
// function and thus the assignment will not be reflected
// to outside this function
}

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #17

P: n/a

"Martijn Lievaart" <m@remove.this.part.rtij.nl> wrote in message
news:pa****************************@remove.this.pa rt.rtij.nl...
On Wed, 07 Jan 2004 10:51:26 +0000, dwizard wrote:
#ifndef point_h
#define point_h

#include "pose.h"

class pose; // <--------- ADD THIS forward decleration

class point
{
public:
void init(pose P);
};

#endif


Won't work. Needs a complete definition of the class to pass to init, a
forward declaration will not do.

HTH,
M4


Say what?

We are only at the declaration stage above. 'point' will have to know all
about 'pose' at implementation but not necessarily at declaration. Consider
all one file...

class pose;

class point {
public:
void init (pose &);
};

class pose {
int i;
friend void point::init (pose &);
};

void point::init (pose &P) {
P.i = 1;
}

int main () {
pose p;
point pt;
pt.init (p);
}

As discussed elsewhere, we probably want to pass 'pose' by reference.

Regards

Brian

Jul 22 '05 #18

P: n/a
On Thu, 08 Jan 2004 10:49:59 -1000, Brian MacBride wrote:
As discussed elsewhere, we probably want to pass 'pose' by reference.


No, we /have/ to pass by reference, otherwise point will not compile.
Without the reference, if we pass by value, point must know the size of a
pose, a forward declaration will not suffice.

M4

Jul 22 '05 #19

P: n/a

"Martijn Lievaart" <m@remove.this.part.rtij.nl> wrote in message
news:pa****************************@remove.this.pa rt.rtij.nl...
On Thu, 08 Jan 2004 10:49:59 -1000, Brian MacBride wrote:
As discussed elsewhere, we probably want to pass 'pose' by reference.


No, we /have/ to pass by reference, otherwise point will not compile.
Without the reference, if we pass by value, point must know the size of a
pose, a forward declaration will not suffice.

M4


class pose;

class point {
public:
void init (pose);
};

class pose {
int i;
friend void point::init (pose);
};

void point::init (pose P) {
P.i = 1;
}

int main () {
pose p;
point pt;
pt.init (p);
}

Are you telling me that the above will not compile?

Regards

Brian
Jul 22 '05 #20

P: n/a
On Thu, 08 Jan 2004 23:08:59 -1000, Brian MacBride wrote:

"Martijn Lievaart" <m@remove.this.part.rtij.nl> wrote in message
news:pa****************************@remove.this.pa rt.rtij.nl...
On Thu, 08 Jan 2004 10:49:59 -1000, Brian MacBride wrote:
> As discussed elsewhere, we probably want to pass 'pose' by reference.
No, we /have/ to pass by reference, otherwise point will not compile.
Without the reference, if we pass by value, point must know the size of a
pose, a forward declaration will not suffice.

(snip code)
Are you telling me that the above will not compile?


Hmmm, it compiles with gcc. I must have had some idee-fix about this, you
seem to be right. Checking the standard .... Yup, you're right, I'm wrong.

M4

Jul 22 '05 #21

This discussion thread is closed

Replies have been disabled for this discussion.