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

Friend in Class Can't Access Private Function

P: n/a
CMain Class is the base class that is initialized in main function. CA
Class is the base class that is initialized in CMain::CMain(). CMain Class
is always public while CA Class is always private. I have placed "friend
void CA::Run_A(void)" in CMain Class. CMain::Run() function attempts to
execute CA::Run_A(), but compiler shows an error saying that it is the
violation to access private function.
I don't understand why because friend should be able to access private
function. Please advise.

/* A.h */
class CMain;

class CA
{
public:
CA(CMain* pMain);
~CA();

private:
CA();
void Run_A(void);
CMain* m_pMain;
};

/* A.cpp */
#include "A.h"

CA::CA()
{

}

CA::CA(CMain* pMain)
{
m_pMain = pMain;
}

CA::~CA()
{

}

void CA::Run_A(void)
{

}

#include <stdio.h>
#include "A.h"

class CMain
{
public:
CMain();
~CMain();
void Run(void);
friend void CA::Run_A(void);

private:
CA* m_pA;
};

CMain::CMain()
{
m_pA = new CA(this);
}

CMain::~CMain()
{
delete m_pA;
}

void CMain::Run(void)
{
CA::Run_A();
}

void main(void)
{
CMain Main;
}
--
Bryan Parkoff
Jul 22 '05 #1
Share this Question
Share on Google+
12 Replies


P: n/a
On Mon, 12 Apr 2004 01:26:08 GMT, "Bryan Parkoff"
<br******************@nospam.com> wrote:
CMain Class is the base class that is initialized in main function. CA
Class is the base class that is initialized in CMain::CMain(). CMain Class
is always public while CA Class is always private. I have placed "friend
void CA::Run_A(void)" in CMain Class. CMain::Run() function attempts to
execute CA::Run_A(), but compiler shows an error saying that it is the
violation to access private function.
I don't understand why because friend should be able to access private
function. Please advise.
You have two problems. Firstly, your CMain class is trying to "claim"
friendship of that function in CA. That's not how it works. The class with
the thing you need access to must /grant/ friendship to the class needing
the access. So you put something like
friend class CMain;
into CA's class definition (or you can limit it to specific functions, as
you've shown you have the general idea about.)

The other thing is that you're calling a member function as if it were a
static function. See below...

/* A.h */
class CMain;

class CA
{
public:
CA(CMain* pMain);
~CA();

private:
CA();
void Run_A(void);
CMain* m_pMain;
};

/* A.cpp */
#include "A.h"

CA::CA()
{

}

CA::CA(CMain* pMain)
{
m_pMain = pMain;
}

CA::~CA()
{

}

void CA::Run_A(void)
{

}

#include <stdio.h>
#include "A.h"

class CMain
{
public:
CMain();
~CMain();
void Run(void);
friend void CA::Run_A(void);

private:
CA* m_pA;
};

CMain::CMain()
{
m_pA = new CA(this);
}

CMain::~CMain()
{
delete m_pA;
}

void CMain::Run(void)
{
CA::Run_A();
Above, you can do something like:
m_pA -> Run_A();
(after your classes have made friends) but you can't call a member function
without an object to invoke it on.
-leor

void main(void)
{
CMain Main;
}


--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: Download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Jul 22 '05 #2

P: n/a
On Mon, 12 Apr 2004 01:47:58 GMT, Leor Zolman <le**@bdsoft.com> wrote:
(after your classes have made friends) but you can't call a member function
without an object to invoke it on.


I'm getting tired. The two places whre I said "member function", what I
really meant was "non-static" member function.
-leor

--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: Download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Jul 22 '05 #3

P: n/a
Leor,

Thank you for the answer. If I place "friend class CMain" in CA class,
all functions and data members will be accessed by CMain class. I do not
allow to happen. What is another way to allow only one private function be
accessed as friend? I don't understand what you mean static or non static
function like outside of class. Please explain.

--
Bryan Parkoff
"Leor Zolman" <le**@bdsoft.com> wrote in message
news:v2********************************@4ax.com...
On Mon, 12 Apr 2004 01:26:08 GMT, "Bryan Parkoff"
<br******************@nospam.com> wrote:
CMain Class is the base class that is initialized in main function. CAClass is the base class that is initialized in CMain::CMain(). CMain Classis always public while CA Class is always private. I have placed "friend
void CA::Run_A(void)" in CMain Class. CMain::Run() function attempts to
execute CA::Run_A(), but compiler shows an error saying that it is the
violation to access private function.
I don't understand why because friend should be able to access privatefunction. Please advise.
You have two problems. Firstly, your CMain class is trying to "claim"
friendship of that function in CA. That's not how it works. The class with
the thing you need access to must /grant/ friendship to the class needing
the access. So you put something like
friend class CMain;
into CA's class definition (or you can limit it to specific functions, as
you've shown you have the general idea about.)

The other thing is that you're calling a member function as if it were a
static function. See below...

/* A.h */
class CMain;

class CA
{
public:
CA(CMain* pMain);
~CA();

private:
CA();
void Run_A(void);
CMain* m_pMain;
};

/* A.cpp */
#include "A.h"

CA::CA()
{

}

CA::CA(CMain* pMain)
{
m_pMain = pMain;
}

CA::~CA()
{

}

void CA::Run_A(void)
{

}

#include <stdio.h>
#include "A.h"

class CMain
{
public:
CMain();
~CMain();
void Run(void);
friend void CA::Run_A(void);

private:
CA* m_pA;
};

CMain::CMain()
{
m_pA = new CA(this);
}

CMain::~CMain()
{
delete m_pA;
}

void CMain::Run(void)
{
CA::Run_A();


Above, you can do something like:
m_pA -> Run_A();
(after your classes have made friends) but you can't call a member

function without an object to invoke it on.
-leor

void main(void)
{
CMain Main;
}


--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: Download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html

Jul 22 '05 #4

P: n/a
On Mon, 12 Apr 2004 02:26:01 GMT, "Bryan Parkoff"
<br******************@nospam.com> wrote:
Leor,

Thank you for the answer. If I place "friend class CMain" in CA class,
all functions and data members will be accessed by CMain class. I do not
allow to happen. What is another way to allow only one private function be
accessed as friend?
In your CA class definition, put:
friend void CMain::Run(void);
to make just that one function of CMain a friend of CA. Since you'd done
this "backwards" in the first place, I just figured you were familiar with
the syntax.

Note that you'll have some ordering issues; I had to put the CMain class
definition up before the CA class definition so that when (in CA) you
declare CMain::Run to be a friend, the compiler recognizes Run as being a
member function of CMain.
I don't understand what you mean static or non static
function like outside of class. Please explain.


All your functions are non-static; that is, they don't use the word
"static" in their declarations. That means they operate upon an object of
their class, not "in a vacuum". Here's your CMain::Run implementation:

void CMain::Run(void)
{
// CA::Run_A();
m_pA->Run_A();
}

The commented-out line is the one you originally had. It says "run the
CA::Run_A() function". But that function can't run without a CA object to
invoke it on. That syntax would only work if CA was a base class of CMain
and had a Run_A function, or if CA::Run_A was a static member function.

This is basic stuff; if you have a C++ book handy, just look up "static
member function".

HTH,
-leor
--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: Download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Jul 22 '05 #5

P: n/a
> In your CA class definition, put:
friend void CMain::Run(void);
to make just that one function of CMain a friend of CA. Since you'd done
this "backwards" in the first place, I just figured you were familiar with
the syntax.

Note that you'll have some ordering issues; I had to put the CMain class
definition up before the CA class definition so that when (in CA) you
declare CMain::Run to be a friend, the compiler recognizes Run as being a
member function of CMain.

It is very close, but one problem exists. I already put "friend void
CMain::Run(void);" inside CA class. The error compiler reports, "C2027: use
of undefined type 'CMain' and see declaration of 'CMain' ".
I made sure to put definition there. I did put "#include "CMain.h"" and
"class CMain;" in A.h and A.cpp. Look at my code below. Please correct my
error.

/////////////////////////////////////////////////////////////////////
#include "CMain.h"

class CMain;

class CA
{
public:
friend void CMain::Run(void);
CA(CMain* pMain);
~CA();

private:
CA();
void Run_A(void);
CMain* m_pMain;
int test;
};
////////////////////////////////////////
////////////////////////////////////////
#include "A.h"
#include "CMain.h"

CA::CA()
{

}

CA::CA(CMain* pMain)
{
m_pMain = pMain;
test = 1024;
}

CA::~CA()
{

}

void CA::Run_A(void)
{

}

Bryan Parkoff
Jul 22 '05 #6

P: n/a
On Mon, 12 Apr 2004 03:32:21 GMT, "Bryan Parkoff"
<br******************@nospam.com> wrote:
In your CA class definition, put:
friend void CMain::Run(void);
to make just that one function of CMain a friend of CA. Since you'd done
this "backwards" in the first place, I just figured you were familiar with
the syntax.

Note that you'll have some ordering issues; I had to put the CMain class
definition up before the CA class definition so that when (in CA) you
declare CMain::Run to be a friend, the compiler recognizes Run as being a
member function of CMain.

It is very close, but one problem exists. I already put "friend void
CMain::Run(void);" inside CA class. The error compiler reports, "C2027: use
of undefined type 'CMain' and see declaration of 'CMain' ".
I made sure to put definition there. I did put "#include "CMain.h"" and
"class CMain;" in A.h and A.cpp. Look at my code below. Please correct my
error.


You don't seem to have shown us CMain.h (and please, please always indicate
the filename of files you post, if there's more than one... best thing is a
comment at the top of the file with the file name, and white space
after...for /each/ file. And include /all/ the files! Thanks.)

The compiler is saying that at the point of that error, it still hasn't
seen the definition for CMain. Here's my test version from yesterday that
does compile; with any luck you'll figure out what you've done wrong by
comparing the ordering of things:
/* A.h */
class CA;

class CMain
{
public:
CMain();
~CMain();
void Run(void);

private:
CA* m_pA;
};

class CA
{
friend void CMain::Run(void);
public:
CA(CMain* pMain) {}
~CA() {}

private:
CA();
void Run_A(void) {}
CMain* m_pMain;
};
// ta.cpp:

#include <stdio.h>
#include "A.h"

CMain::CMain()
{
m_pA = new CA(this);
}

CMain::~CMain()
{
delete m_pA;
}

void CMain::Run(void)
{
// CA::Run_A();
m_pA->Run_A();
}

void main(void)
{
CMain Main;
}
-leor

--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: Download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Jul 22 '05 #7

P: n/a
"Leor Zolman" <le**@bdsoft.com> wrote in message
news:t7********************************@4ax.com...
<<snip>>
/* A.h */
class CA;

class CMain
{
public:
CMain();
~CMain();
void Run(void);

private:
CA* m_pA;
};

class CA
{
friend void CMain::Run(void);
public:
CA(CMain* pMain) {}
~CA() {}

private:
CA();
void Run_A(void) {}
CMain* m_pMain;
};
// ta.cpp:

#include <stdio.h>
#include "A.h"

CMain::CMain()
{
m_pA = new CA(this);
}

CMain::~CMain()
{
delete m_pA;
}

void CMain::Run(void)
{
// CA::Run_A();
m_pA->Run_A();
}

void main(void)
{
CMain Main;
}

Leor, when I compiled your "fixed" program I got the following error.

E:/DPR226/My Files/ta.cpp:23:'main' must return 'int'

Otherwise, it seemed okay.
--
Gary
Jul 22 '05 #8

P: n/a
On Mon, 12 Apr 2004 10:18:47 -0400, "Gary Labowitz" <gl*******@comcast.net>
wrote:
void main(void)
{
CMain Main;
}

Leor, when I compiled your "fixed" program I got the following error.

E:/DPR226/My Files/ta.cpp:23:'main' must return 'int'

Otherwise, it seemed okay.


That's what I get for not compiling this with Comeau ;-)

I was just addressing the specific access and ordering issues the OP had
been struggling with, in this case, but of course main should return int.
-leor
--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: Download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Jul 22 '05 #9

P: n/a
"Leor Zolman" <le**@bdsoft.com> wrote in message
news:ub********************************@4ax.com...
On Mon, 12 Apr 2004 10:18:47 -0400, "Gary Labowitz" <gl*******@comcast.net> wrote:
void main(void)
{
CMain Main;
}

Leor, when I compiled your "fixed" program I got the following error.
E:/DPR226/My Files/ta.cpp:23:'main' must return 'int'

Otherwise, it seemed okay.


That's what I get for not compiling this with Comeau ;-)


Isn't it psychologically interesting what amuses us when we are
unemployed?
--
Gary
Jul 22 '05 #10

P: n/a
Leor,

I have compiled successfully. The one problem is that I do not want to
put CMain class in A.h, but it should be in CMain.h. I did put the
declaration of "class CMain;" before the definition of "class CA". Why is
it required that class CMain be having a definition before class CA? I
would not want to put more than one definition of class CMain in each header
files. I have to include all source code for one more time.
Why CMain::Run() is allowed to access int CA::test that is private? I
thought that it is allowed to access private function only. Do you
recommend to add const after CMain::Run () so it would prevent int CA::test
from modification?

/* A.h */
#ifndef A_H
#define A_H

#include "CMain.h"

class CMain;

class CA
{
public:
friend void CMain::Run(void);
CA(CMain* pMain);
~CA();
private:
CA();
void Run_A(void);
CMain* m_pMain;
int test;
};

#endif
/* A.h */
/* A.cpp */
#include "A.h"
#include "CMain.h"

CA::CA()
{

}

CA::CA(CMain* pMain)
{
m_pMain = pMain;
test = 1024;
}

CA::~CA()
{

}

void CA::Run_A(void)
{

}
/* A.cpp */
/* CMain.h */
#ifndef CMAIN_H
#define CMAIN_H

#include "A.h"

class CA;

class CMain
{
public:
CMain();
~CMain();
void Run(void);
void Run2(void);

private:
CA* m_pA;
};

#endif
/* CMain.h */
/* CMain.cpp */
#include "CMain.h"
#include "A.h"

CMain::CMain()
{
m_pA = new CA(this);
}

CMain::~CMain()
{
delete m_pA;
}

void CMain::Run(void)
{
m_pA->Run_A();
m_pA->test = 1;
Run2();
}

void CMain::Run2(void)
{
// m_pA->test = 2;
}
/* CMain.cpp */
/* Main.cpp */
#include <stdio.h>
#include "CMain.h"

void main(void)
{
CMain Main;
Main.Run();
}
/* Main.cpp */
--
Bryan Parkoff
"Leor Zolman" <le**@bdsoft.com> wrote in message
news:t7********************************@4ax.com...
On Mon, 12 Apr 2004 03:32:21 GMT, "Bryan Parkoff"
<br******************@nospam.com> wrote:
In your CA class definition, put:
friend void CMain::Run(void);
to make just that one function of CMain a friend of CA. Since you'd done this "backwards" in the first place, I just figured you were familiar with the syntax.

Note that you'll have some ordering issues; I had to put the CMain class definition up before the CA class definition so that when (in CA) you
declare CMain::Run to be a friend, the compiler recognizes Run as being a member function of CMain. It is very close, but one problem exists. I already put "friend void
CMain::Run(void);" inside CA class. The error compiler reports, "C2027: useof undefined type 'CMain' and see declaration of 'CMain' ".
I made sure to put definition there. I did put "#include "CMain.h"" and"class CMain;" in A.h and A.cpp. Look at my code below. Please correct myerror.


You don't seem to have shown us CMain.h (and please, please always

indicate the filename of files you post, if there's more than one... best thing is a comment at the top of the file with the file name, and white space
after...for /each/ file. And include /all/ the files! Thanks.)

The compiler is saying that at the point of that error, it still hasn't
seen the definition for CMain. Here's my test version from yesterday that
does compile; with any luck you'll figure out what you've done wrong by
comparing the ordering of things:
/* A.h */
class CA;

class CMain
{
public:
CMain();
~CMain();
void Run(void);

private:
CA* m_pA;
};

class CA
{
friend void CMain::Run(void);
public:
CA(CMain* pMain) {}
~CA() {}

private:
CA();
void Run_A(void) {}
CMain* m_pMain;
};
// ta.cpp:

#include <stdio.h>
#include "A.h"

CMain::CMain()
{
m_pA = new CA(this);
}

CMain::~CMain()
{
delete m_pA;
}

void CMain::Run(void)
{
// CA::Run_A();
m_pA->Run_A();
}

void main(void)
{
CMain Main;
}
-leor

--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: Download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html

Jul 22 '05 #11

P: n/a
On Mon, 12 Apr 2004 18:36:01 GMT, "Bryan Parkoff"
<br******************@nospam.com> wrote:
Leor,

I have compiled successfully. The one problem is that I do not want to
put CMain class in A.h, but it should be in CMain.h.
I didn't mean to imply it /should/ be in the same file; I was just trying
to show the shortest possible sample program that illustrates the ordering
dependency. If you have things organized with one class definition per
header file, just make sure the compiler "sees" the CMain class definition
before it tries to compile the CA class definition.
I did put the
declaration of "class CMain;" before the definition of "class CA".
Why is
it required that class CMain be having a definition before class CA?
You aren't allowed to use the name "CMain::run" the way you do in your
friend declaration if the compiler has not yet seen CMain's class
definition. How can the compiler be sure there /is/ a CMain::run() ?
I
would not want to put more than one definition of class CMain in each header
files. I have to include all source code for one more time.
Why CMain::Run() is allowed to access int CA::test that is private?
Because you've declared CMain::Run() to be a friend of CA. That's what
friends are for [for good times, and bad times... ;-) ]
I
thought that it is allowed to access private function only.
It is allowed to access private /everything/. Look, my friend, please find
yourself a C++ book and read up all about the "friend" feature.
Do you
recommend to add const after CMain::Run () so it would prevent int CA::test
from modification?
I have no opinion whether you should make Run a const member function or
not; it depends on what it is supposed to do. Rather than trying to give
you a lesson here on when and where const member functions are appropriate,
I'd prefer to just send you to that same book to look up "const member
functions".

Good luck,
-leor

/* A.h */
#ifndef A_H
#define A_H

#include "CMain.h"

class CMain;

class CA
{
public:
friend void CMain::Run(void);
CA(CMain* pMain);
~CA();
private:
CA();
void Run_A(void);
CMain* m_pMain;
int test;
};

#endif
/* A.h */
/* A.cpp */
#include "A.h"
#include "CMain.h"

CA::CA()
{

}

CA::CA(CMain* pMain)
{
m_pMain = pMain;
test = 1024;
}

CA::~CA()
{

}

void CA::Run_A(void)
{

}
/* A.cpp */
/* CMain.h */
#ifndef CMAIN_H
#define CMAIN_H

#include "A.h"

class CA;

class CMain
{
public:
CMain();
~CMain();
void Run(void);
void Run2(void);

private:
CA* m_pA;
};

#endif
/* CMain.h */
/* CMain.cpp */
#include "CMain.h"
#include "A.h"

CMain::CMain()
{
m_pA = new CA(this);
}

CMain::~CMain()
{
delete m_pA;
}

void CMain::Run(void)
{
m_pA->Run_A();
m_pA->test = 1;
Run2();
}

void CMain::Run2(void)
{
// m_pA->test = 2;
}
/* CMain.cpp */
/* Main.cpp */
#include <stdio.h>
#include "CMain.h"

void main(void)
{
CMain Main;
Main.Run();
}
/* Main.cpp */


--
Leor Zolman --- BD Software --- www.bdsoft.com
On-Site Training in C/C++, Java, Perl and Unix
C++ users: Download BD Software's free STL Error Message Decryptor at:
www.bdsoft.com/tools/stlfilt.html
Jul 22 '05 #12

P: n/a
> It is allowed to access private /everything/. Look, my friend, please find
yourself a C++ book and read up all about the "friend" feature.


If it is the way how C++ Compiler is designed that it can't accept
incomplete class declaration like "class CMain;" before "class CA", I am not
satisified. I have the book called, "C++ Primer Third Edition by Stanley B.
Lippman and Josee Lajoie" It does explain friend in class, but it does not
say like my example source code here in this newsgroups.

Bryan Parkoff
Jul 22 '05 #13

This discussion thread is closed

Replies have been disabled for this discussion.