Accessing a class object within a class from a class - c++

I know this title is a bit confusing but a diagram will probably help.
in one file:
#ifndef ...
#def ...
#includes (including OListiterator.h>
template <class T>
class OList;
template <class T>
Class OListiterator{
friend class OList<T>::OList;
typename OList<T>::Node* iiter;
};
function defs;
#endif
in another:
#ifndef ...
#def ...
#includes (one is OList.h)
template<class T>
class OListiterator;
template <class T>
Class OList{
friend class OListiterator<T>::OListiterator;
public:
class Node{
};
//things
};
//functions
#endif
This is what myself and the TA assisting me would have thought would work, but I am thrown the error: Node does not name a type in OList. Does anybody know why/how I can fix this? Let me know if I need to post more.

It looks like there is a dependency here. OList needs OListIterator, and vice versa. The way to solve this is to change your design so this dependency is not needed. Try placing your OListIterator design so it can be used inside the OList.

You need a forward declaration of class OList:
// forward declaration
template <class T>
class OList;
template <class T>
class OListiterator{
friend class OList<T>::OList;
typename OList<T>::Node* iiter;
};
template <class T>
class OList{
friend class OListiterator<T>::OListiterator;
public:
class Node{
};
};
Demo
Note that friend class OList<T>::OList; is equivalent to just friend class OList<T>; because OList<T>::OList is class name injected in scope of OList<T>.

When you name the member Node of OList as a friend, the compiler needs the entire definition of OList to ensure that there is such a member.
The solution would be to break the dependency. Why does a list node need to have access to the list iterator's internals? Seems to me like it should be the other way around.

Related

C++: Can a Template be friend of a Class?

Is it possible to make friend of a class, all possible variants of a class-template?
Just to clarify, for example, something like this:
class A
{ friend template B; } // syntactic error yeah
So any B<X> variant could manipulate any protected attribute of A.
A is an small and simple class with a lot of friends who manipulate its attributes. Just one of then need to be a template. I know that I can do this:
template <class T>
class A
{ friend class B<T>; }
But so I would have to change my code in all the other friends and I would like to avoid it.
You may define a friend template class like that:
class A{
template<typename T>
friend class B;
};
That would make every specialization of class B a friend of class A. I've had a similar question that had the opposite goal: to restrict some specializations: Friend template function instantiations that match parameter

Class is not a class template

i get the error : class is not a class template .Any idea why?
template<class T>
class nod{
friend class lista<T>;
protected:
T info;
nod<T> *urm,*prec;
};
lista is not known yet at this point in the code. So of course the compiler doesn't think it's a template class. You need to forward declare it with its template arguments. See also: How to forward declare a C++ template class?

Template class friendship

I recently came across a c++ piece of code where a class is made friend to itself. As I have read on different forums a class is already a friend to itself. So I was wondering if there is a specific reason why one would want to make a class friend to itself explicitly.
Another question would be, what's the reason in making a class a friend of itself?
Maybe someone with a lot of experience can clarify this topic.
Here is the code example, to illustrate my question:
template < typename T>
class Foo: public T
{
protected:
template < typename U>
friend class Foo;
}
There's no point indeed to make a class a friend to itself, except if it is a template class. For example the following code makes sense:
template <class T>
class A
{
template<class U>
friend class A;
}
An STL example is the std::_Ptr_base which is the base class for std::shared_ptr and std::weak_ptr.
It is not making the class a friend of itself, it is making all classes of that template a friend to all others. So A<Foo> is a friend of A<Bar> which is a different class.
I am surprised the syntax is as you print it and not template<typename U> friend class A<U>; but that is what it actually means.

Can one template class can be friend of another template class in c++?

I have a two template class, templateClass1 and templateClass2. I want to use private variables and methods of templateClass1 in templateClass2. Is it possible to do so by using friend keyword in c++ ?
Sumit
I know this post is probably dead, but for other people who stumble upon this...
templateClass1.h
template <class T> class templateClass2; // forward declare
template <typename T>
class templateClass1 {
friend templateClass2<T>;
};
templateClass2.h
template <class T> class templateClass1; // forward declare
template <typename T>
class templateClass2 {
friend templateClass1;
}
It is possible to have a friends of any type, but a template is not a type until its template arguments have been supplied. So in general you would have to have a specialization for each full type you wish to be friends with. This will push you toward attempting to pass the type to be friend as a template parameter, but you can not supply a template type that will be friended.
for ex. this is illegal
template <class T>
class A
{
friend class T;
};
with those stipulations it makes it very difficult to do anything meaning full with templates and friendedness.

Is there a way to have a single static variable for a template class (for all types) without breaking encapsulation

I need a way to have a single static variable for all kinds of types of my template class
template <class T> class Foo { static Bar foobar;};
Well, the line above will generate a Bar object named foobar for every type T, but this is not what i want, i basically want a way to declare a variable of type Bar, so every object of type Foo has access to the same foobar variable, independent of T.
I tried to use another class to store the private stuff, but that doesnt work, because the standard does not allow stuff like template <class T> friend class Foo<T>;
So the obvious solution (shown below) is to have a global variable Bar foobar, but this obviously violates the information hiding concept (of proper encapsulation):
Bar Foo_DO_NOT_TOUCH_THIS_PLEASE_foobar;
template <class T> class Foo { static Bar& foobar;};
template <class T> Bar& Foo<T>::foobar=Foo_DO_NOT_TOUCH_THIS_PLEASE_foobar;
Ofcourse you can additionally use a detail namespace (thats what i am currently doing), but is there another way which really prohibits users from messing around with your private static variables ?
Additonally this solution will get quite messy when you have to declare lots of static methods in a similar fashion, because you will most likely have to extensivly use the friend keyword like friend RetType Foo_detail::StaticFunc(ArgT1, ArgT2).
And the users wont have a nice interface since they cant use those functions like they are used to Foo<T>::someFunc() but instead they will have to call something like Foo_static::someFunc() (if you use the namespace Foo_static for public static functions).
So is there any other solution which does not break encapsulation, and/or does not introduce lots of syntax overhead ?
EDIT:
based on all your anwsers, i tried following, and it works as intended:
typedef int Bar;
template <class T> class Foo;
class FooBase
{
static Bar foobar;
public:
template <class T> friend class Foo;
};
Bar FooBase::foobar;
template <class T> class Foo : public FooBase
{
public:
using FooBase::foobar;
};
this solution has the benefit, that users can not inherit from FooBase.
Perhaps inherit the static member?
class OneBarForAll
{
protected:
static Bar foobar;
};
template <class T>
class Foo : public OneBarForAll
{
};
Lots of Foo<T>'s will be made, but only one OneBarForAll.
One potential problem with this is that there's nothing stopping other users of the code from inheriting from OneBarForAll and modifying foobar anyway.
Ideally you do want the template friend, as that best describes the access requirements of your design, but C++ does not currently allow that.
The syntax for
template <class T> friend class Foo<T>;
is
template <class T> friend class Foo;
(which means that every instantiation of Foo is a friend of the class you define it in)
So perhaps you can go with the solution you ruled out before.
you could do:
struct Base {
static Foo foo;
};
//init foo here
template<typename T>
struct Derived : Base {
...
};
...
Derived<Bar>::foo;
It works in g++
Why not inherit from a non-template base class?