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

How to make a sub class a friend in another class?

P: n/a
Short version:
class MyClass
{
friend class MyOtherClass::MySubClass; // Doesn't work
};

class MyOtherClass
{
class MySubClass
{
// Need to access private members of MyClass here
} MySubInstance;
};

Here is something more close to what I am trying to do showing the problem:

#include <iostream>
#include <string>

class COffsetMap
{
public:
void SetBase( void* Base ) { }
void SetOffset( int& Var ) { }
};

class CHealth
{
public:
friend class CCharacter::CCharFieldMap; // Doesn't work
private:
int Mana_;
int ManaMax_;
};

class CCharacter
{
public:
class CCharFieldMap: public COffsetMap
{
public:
void SetMap( CCharacter* Base )
{
SetBase( Base );
SetOffset( Base->Version );
SetOffset( Base->Health.Mana_ ); // Can't access private
SetOffset( Base->Health.ManaMax_ ); // Can't access private
}
} CharFieldMap;

private:
int Version;
CHealth Health;

};

int main()
{
CCharacter Char;

std::cout << "Press Return";
std::string wait;
std::getline( std::cin, wait );
return 0;
}
I've tried various ways around this to no avail. Is this possible?
Aug 21 '06 #1
Share this Question
Share on Google+
6 Replies


P: n/a
Jim Langston wrote:
Short version:
class MyClass
{
friend class MyOtherClass::MySubClass; // Doesn't work
};

class MyOtherClass
{
class MySubClass
{
// Need to access private members of MyClass here
} MySubInstance;
};
Do it the other way round:

class MyOtherClass
{
friend class MyClass;

class MySubClass
{
// Need to access private members of MyClass here
} MySubInstance;
};

class MyClass
{
friend class MyOtherClass::MySubClass; // Does work
};
--
Ian Collins.
Aug 21 '06 #2

P: n/a
"Ian Collins" <ia******@hotmail.comwrote in message
news:4k************@individual.net...
Jim Langston wrote:
>Short version:
class MyClass
{
friend class MyOtherClass::MySubClass; // Doesn't work
};

class MyOtherClass
{
class MySubClass
{
// Need to access private members of MyClass here
} MySubInstance;
};
Do it the other way round:

class MyOtherClass
{
friend class MyClass;

class MySubClass
{
// Need to access private members of MyClass here
} MySubInstance;
};

class MyClass
{
friend class MyOtherClass::MySubClass; // Does work
};
That doesn't work, because (as I forgot to show in my short version)
MyOtherClass has a private instance of MyClass in it.

If I declare MyClass after MyOtherClass than I get the error
error C2079: 'CCharacter::Health' uses undefined class 'CHealth'
even if I do
class MyClass;

Even if I make the instance a pointer declartion with
MyClass* MyInstance;
then MySubClass gets errors when it attempts to access the variables:
error C2027: use of undefined type 'CHealth'
see declaration of 'CHealth'

I even tried taking the class definition of MySubClass out of MyOtherClass
but then I get the problem that MySubClass needs to see the definition of
MyClass to access the variables, but as you seem to indicate, MyClass also
needs to see the definition of MyOtherClass first.

ug.

Can you get this to compile by any manipulations?

#include <iostream>
#include <string>

class COffsetMap
{
public:
void SetBase( void* Base ) { }
void SetOffset( int& Var ) { }
};

class CCharacter
{
public:
class CCharFieldMap: public COffsetMap
{
public:
void SetMap( CCharacter* Base )
{
SetBase( Base );
SetOffset( Base->Version );
SetOffset( Base->Health->Mana_ );
SetOffset( Base->Health->ManaMax_ );
}
} CharFieldMap;

private:
int Version;
CHealth* Health;

};

class CHealth
{
public:
friend class CCharacter::CCharFieldMap; // Doesn't work
private:
int Mana_;
int ManaMax_;
};

int main()
{
CCharacter Char;
Char.SetMap( &Char );

std::cout << "Press Return";
std::string wait;
std::getline( std::cin, wait );
return 0;
}


Aug 21 '06 #3

P: n/a
Jim Langston wrote:
>
That doesn't work, because (as I forgot to show in my short version)
MyOtherClass has a private instance of MyClass in it.

If I declare MyClass after MyOtherClass than I get the error
error C2079: 'CCharacter::Health' uses undefined class 'CHealth'
even if I do
class MyClass;

Even if I make the instance a pointer declartion with
MyClass* MyInstance;
then MySubClass gets errors when it attempts to access the variables:
error C2027: use of undefined type 'CHealth'
see declaration of 'CHealth'

I even tried taking the class definition of MySubClass out of MyOtherClass
but then I get the problem that MySubClass needs to see the definition of
MyClass to access the variables, but as you seem to indicate, MyClass also
needs to see the definition of MyOtherClass first.

ug.

Can you get this to compile by any manipulations?

#include <iostream>
#include <string>

class COffsetMap
{
public:
void SetBase( void* Base ) { }
void SetOffset( int& Var ) { }
};

class CCharacter
{
public:
class CCharFieldMap: public COffsetMap
{
public:
void SetMap( CCharacter* Base )
{
SetBase( Base );
SetOffset( Base->Version );
SetOffset( Base->Health->Mana_ );
SetOffset( Base->Health->ManaMax_ );
}
} CharFieldMap;

private:
int Version;
CHealth* Health;

};
Why not untangle the dependencies and extract CCharFieldMap from its
containing class?

--
Ian Collins.
Aug 21 '06 #4

P: n/a
"Ian Collins" <ia******@hotmail.comwrote in message
news:4k************@individual.net...
Jim Langston wrote:
>>
That doesn't work, because (as I forgot to show in my short version)
MyOtherClass has a private instance of MyClass in it.

If I declare MyClass after MyOtherClass than I get the error
error C2079: 'CCharacter::Health' uses undefined class 'CHealth'
even if I do
class MyClass;

Even if I make the instance a pointer declartion with
MyClass* MyInstance;
then MySubClass gets errors when it attempts to access the variables:
error C2027: use of undefined type 'CHealth'
see declaration of 'CHealth'

I even tried taking the class definition of MySubClass out of
MyOtherClass
but then I get the problem that MySubClass needs to see the definition of
MyClass to access the variables, but as you seem to indicate, MyClass
also
needs to see the definition of MyOtherClass first.

ug.

Can you get this to compile by any manipulations?

#include <iostream>
#include <string>

class COffsetMap
{
public:
void SetBase( void* Base ) { }
void SetOffset( int& Var ) { }
};

class CCharacter
{
public:
class CCharFieldMap: public COffsetMap
{
public:
void SetMap( CCharacter* Base )
{
SetBase( Base );
SetOffset( Base->Version );
SetOffset( Base->Health->Mana_ );
SetOffset( Base->Health->ManaMax_ );
}
} CharFieldMap;

private:
int Version;
CHealth* Health;

};
Why not untangle the dependencies and extract CCharFieldMap from its
containing class?
Tried that too. Couldn't get it to work either.

I even took the declaration/definition of CCharFieldMap out of CCharacter,
then in CCharacter I only do
CCharFieldMap CharFieldMap;
but that still wouldn't compile.

CCharFieldMap needs to be in CCharacter for usage. Otherwise it will
complicate usage quite a bit.
Aug 21 '06 #5

P: n/a
Jim Langston wrote:
"Ian Collins" <ia******@hotmail.comwrote in message
>>
Why not untangle the dependencies and extract CCharFieldMap from its
containing class?


Tried that too. Couldn't get it to work either.

I even took the declaration/definition of CCharFieldMap out of CCharacter,
then in CCharacter I only do
CCharFieldMap CharFieldMap;
but that still wouldn't compile.

CCharFieldMap needs to be in CCharacter for usage. Otherwise it will
complicate usage quite a bit.
It can still be a member, even if it isn't a nested class.

If you can't get it to compile in one file, give each class its own
header and source file and use appropriate forward declarations in the
headers. If that doesn't work, your design is too tangled and will have
to change.

--
Ian Collins.
Aug 21 '06 #6

P: n/a
"Ian Collins" <ia******@hotmail.comwrote in message
news:4k************@individual.net...
Jim Langston wrote:
>"Ian Collins" <ia******@hotmail.comwrote in message
>>>
Why not untangle the dependencies and extract CCharFieldMap from its
containing class?


Tried that too. Couldn't get it to work either.

I even took the declaration/definition of CCharFieldMap out of
CCharacter,
then in CCharacter I only do
CCharFieldMap CharFieldMap;
but that still wouldn't compile.

CCharFieldMap needs to be in CCharacter for usage. Otherwise it will
complicate usage quite a bit.
It can still be a member, even if it isn't a nested class.

If you can't get it to compile in one file, give each class its own
header and source file and use appropriate forward declarations in the
headers. If that doesn't work, your design is too tangled and will have
to change.
Well, I finally got it to compile. It's just very tricky in that things
have to be done in an exact order. Makes it a little difficult for the
user.

#include <iostream>
#include <string>

class COffsetMap
{
public:
void SetBase( void* Base ) { }
void SetOffset( int& Var ) { }
};

class CHealth
{
public:
friend class CCharFieldMap;
private:
int Mana_;
int ManaMax_;
};

class CCharacter;

class CCharFieldMap: public COffsetMap
{
public:
void SetMap( CCharacter* Base );
};

class CCharacter
{
public:
friend class CCharFieldMap;
CCharFieldMap CharFieldMap;

private:
int Version;
CHealth Health;

};

void CCharFieldMap::SetMap( CCharacter* Base )
{
SetBase( Base );
SetOffset( Base->Version );
SetOffset( Base->Health.Mana_ );
SetOffset( Base->Health.ManaMax_ );
}

int main()
{
CCharacter Char;
Char.CharFieldMap.SetMap( &Char );

std::cout << "Press Return";
std::string wait;
std::getline( std::cin, wait );
return 0;
}
Aug 22 '06 #7

This discussion thread is closed

Replies have been disabled for this discussion.