Include nested class in C++ public header - c++

I have a public header that has class X. X has a private member of nested type U::V. As I understand, normally, you just forward declare the types but I cant forward declare nested type. U::V is in a private header so I cannot #include them from a public header. What do I do to have X know of class U::V?
Summary of my code:
// in include/mylib/box.h
class X {
public:
X();
//...
private:
U::V stuffs; // how do I have this declaration work?
};
// in some private file
class U {
class V{
// ..
};
};

What do I do to have X know of class U::V?
Only way to have a member of type U::V in X is to define the type U::V before defining X.
You can avoid storing the member directly by using the PIMPL idiom. In short, you would store a pointer to a forward-declared type.

This question was answered by Adam Rosenfield here.
You'll have to un-nest at least one of the nested classes

I just realized this happens because I got an incomplete class definition, not because it's a nested class. Thanks, everyone.

Related

Making a struct in a class

I came across code with the following format:
class A {
typedef struct {
// variables of struct B
} B
// private and public variables, member functions of class A
}
What is the point of putting a struct in a class instead of outside of it ?
And who gets to access the struct if it is placed in a class ?
Only the class or can another class use it too ?
Thank you in advance :D
in C++, an 'inside' class is essentially under a 'namespace' of the outer class.
That is, you access it using A::B from anywhere, as long as it is public.
It's not like Java where the inner class is related to a pointer of the outer class. You don't need an A* to have an A::B*.
They have no low-level connection and the inner class cannot see anything in the outer class without a given outer-class pointer.

Accessing constructor of private or protected class?

If I have a subclass which should only be instantiated by its parent class, is friend the appropriate method for accessing the constructor of the private or protected class?
To clarify, there are already questions where this is proposed as the answer. My question is specifically regarding whether this is the only answer and, if not, whether it is the most appropriate for this situation.
Example:
class Class_A {
public:
class Class_B {
// Adding 'friend' keyword here
friend class Class_A;
int _value;
Class_B(
int value)
:
_value(value)
{
}
};
protected:
static Class_A::Class_B createB(
int value)
{
return Class_B(value);
}
};
Credit goes to #Angew for correcting the first version of this answer. Here comes the update:
You are actually using the wrong term: Class_B is not a subclass of Class_B. The correct term is : nested class. The relationship implied by declaring one class inside another is the following one:
The nested class is a member of the enclosing one, and thus has the same access rights as a member (the nested class is basically an implicit friend of the enclosing class).
I.e. the nested class has access to protected and private members of the enclosing class, but not the other way around. Thus if you want to call a private or protected method (e.g. constructor) making them friends is the way to go.

Nested classes - separating the declaration from the definition in C++

Is it possible to separate class declaration from its definition? Of course it is, but what if I want to have an object of this class before the actual definition of it? Consider the following example:
class ID3_Reader{
public:
// code omitted for brevity
protected:
class Mp3_File;
Mp3_File mFile;
};
It's obvious that it will not compile. I would have to define the Mp3_File class inside the ID3_Reader class. It's not a problem when I have just two classes. What if there would be like five of them? My code would become pretty messy. To avoid this problem I would have to separate the class declarations from their definitions. How can I achieve that? Remember that I need an instance of the Mp3_File class inside the ID3_Reader class.
The reason why I'm using nested classes is because I don't want some other programmer to use the Mp3_File class. I used "protected" keyword because I will create classes based on the ID3_Reader class.
You can achive this by using a pointer like the other guys answered:
class Mp3_File; // forward declaration of class Mp3_File
class ID3_Reader{
public:
// code omitted for brevity
protected:
Mp3_File *mFile;
};
Or you can declare the constructor of class Mp3_File private and declare class ID3_Reader friend of class Mp3_File:
class Mp3_File {
Mp3_File() {} // constructor is private
friend class ID3_Reader;
};
class ID3_Reader{
public:
// code omitted for brevity
protected:
Mp3_File mFile;
};
auto main() -> int {
ID3_Reader r;
Mp3_File m; // Error Mp3_File constructor is private!
return 0;
}
Thus, other people won't be able to use Mp3_File while you can use it in the scope of class ID3_Reader.
It won't compile because the compiler doesn't know how much memory that Mp3_File class will use. If you change it to a pointer
class ID3_Reader{
public:
// code omitted for brevity
protected:
class Mp3_File;
Mp3_File *mFile;
};
that compiles just fine (a pointer has a fixed size - http://ideone.com/VmmXfK).
I suggest using a pointer instead of a complete member variable and initialize/deinitialize it in the ctor/dtor.
I don't see another way of doing it without changing the "nested classes" design.
You can achieve that by using pointers. Recall that although you must have a full class to define a variable, a simple forward declaration is good to define a pointer:
class ID3_Reader{
public:
// code omitted for brevity
protected:
class Mp3_File;
Mp3_File *mFile;
};
Unfortunately, this puts you on the hook for managing the memory for the nested class, but it does hide all of the internals of the class from outside programmers.
Instead of defining mFile as an instance of Mp3_File, define it as a pointer to an Mp3_File. That way you won't need to know the definition in the header file. Or better yet - use a smart pointer. You will then need to create the real instance by using new in the class constructor and delete it in ID3_Reader's destructor.
If you wish to stay with your current syntax to access mFile from outside of the class, dereference it inside the accessor function:
Mp3_File& getMp3(){ return *mFile; };
Then - if Mp3_File has an overloaded operator() (or any other overloaded operator as a matter of fact), you won't need to dereference it every time manually.
You can make your class a class template to work around this restriction: for class templates the definition of the nested type needs to be visible at instantiation time, not while looking at the definition of the class template. You might want to use a typedef to actually name the used instantiation to avoid the need to have a trailing <>. Here is a quick demo:
template <typename = void>
class ID3_ReaderT {
public:
// code omitted for brevity
protected:
class Mp3_File;
Mp3_File mFile;
};
typedef ID3_Reader<> ID3_Reader;
template <typename T>
class ID3_ReaderT<T>::Mp3_File {
};
int main()
{
ID3_Reader reader;
}
Of course, it still means that every user of ID3_Reader needs to see the definition of the nested type. If you want to avoid that, your option is on level indirection, i.e., using a pointer as was already stated by multiple answers.

Can't access members of a Template base class within a derived template class

I have a template base class.Lets say.
template<class KeyF>
class Base
{
private:
int member1;
char member2;
....
};
I derived another class from above class.
template<class KeyF>
class Derived : public Base<KeyF>
{
public:
void func1() {
<accessing member1/member2>
}
....
};
Above code doesn't compile in gcc. saying that member1 is not a member of Derived. But it is already derived from a Base Class, then why can't it access its member?
Members in Base are private. You cannot access private members of class, outside of this class (except friend). Make them protected, or make protected getters.
You need to prefix base member names with this-> or Base<KeyF>::, or add a using declaration to the class to unhide them. Their names are dependent names, and they are hidden.
Did you try protected? Been a bit since I was deep into C++...
I think two changes needed to solve the issue:
In base class, define the member as "protected" instead of "private" to be accessible in the derived class.
In derived class, add the base class name ahead of the protected member. In this case, it should look like "Base<typename>::member1".
Using C++17 standard in my case, the issue was resolved. Hope this is helpful. Thanks to Kerrek SB for the info.

Is it possible to declare a class without implementing it? (C++)

I know the questions seems ambiguous, but I couldn't think of any other way to put it, but, Is it possible to do something like this:
#include<iostream>
class wsx;
class wsx
{
public:
wsx();
}
wsx::wsx()
{
std::cout<<"WSX";
}
?
Yes, that is possible. The following just declares wsx
class wsx;
That kind of declaration is called a forward declaration, because it's needed when two classes refer to each other:
class A;
class B { A * a; };
class A { B * b; };
One of them needs to be forward declared then.
In your example,
class wsx; // this is a class declaration
class wsx // this is a class definition
{
public:
wsx();
}
So yes, by using class wsx; it is possible to declare a class without defining it. A class declaration lets you declare pointers and references to that class, but not instances of the class. The compiler needs the class definition so it knows how much memory to allocate for an instance of the class.
This is the definition of the class
class wsx
{
public:
wsx();
}
This is the definition of the constructor
wsx::wsx()
{
std::cout<<"WSX";
}
THis is a forward declaration that says the class WILL be defined somewhere
class wsx;
Yes. But it is not possible to define a class without declaring it.
Because: Every definition is also a declaration.
You did define the class. It has no data members, but that's not necessary.
I'm not sure what you mean. The code you pasted looks correct.