C++: Two classes needing each other - c++

I'm making a game and I have a class called Man and a class called Block in their code they both need each other, but they're in seperate files. Is there a way to "predefine" a class? Like Objective-C's #class macro?

Yes.
class Man;
This will declare Man as an "incomplete type". You can declare pointers or references to it and a few other things, but you can't create an instance or access members of it. This isn't a complete description of what you can and can't do with an incomplete type, but it's the general idea.

It's called a circular dependency. In class Two.h
class One;
class Two {
public:
One* oneRef;
};
And in class One.h
class Two;
class One {
public:
Two* twoRef;
};
The "class One;" and "class Two;" directives allocate a class names "One" and "Two" respectively; but they don't define any other details beyond the name. Therefore you can create pointers the class, but you cannot include the whole class like so:
class One;
class Two : public One {
};
class Three {
public:
One one;
};
The reason the two examples above won't compile is because while the compiler knows there is a class One, it doesn't know what fields, methods, or virtual methods, class One might contain because only the name had been defined, not the actual class definition.

Related

C++ - Is possible to have subclass contain the containing class by value?

class Containing{
class Subclass{
Containing cont;
};
};
Currently this says "error: field cont has incomplete type". Is this not possible at all with C++? Or when someone needs this does it mean they have wrong program design? Should Subclass be a derived / separate class instead?
This is the same problem as
class Containing;
class Subclass
{
Containing cont;
};
You can solve it in the same way as the non-nested problem, by defining the dependent class after the class it depends on.
class Containing
{
class Subclass;
};
class Containing::Subclass
{
Containing cont;
};
I think what you want could be a pointer:
class Containing;
class Containing{
class Subclass{
Containing* cont;
};
};
In Java, class instances are pointers by default. This means that this is just an address value which contains the address of the Containing object. So the cont is a separate instance which you refer to by the pointer. Your code doesn't work because the declaration of Containing isn't finished, thus Containing isn't known yet. It would need its own declaration to finish its own declaration.
What I did above the class is a forward declaration. This means I told the compiler that there is a class with the name Containing declared. Then you can use a pointer to Containing, because you don't have to know anything about the members or the size of Containing.
Be aware, that you by default have no pointer, you first need an instance of Subclass, maybe this is even what you want:
class Containing;
class Containing{
Containing* cont;
};

Shortcut to nested type in C++ class

In a generated class I have an anonymous enum with many members, some with long names, like this:
class ContainerClass {
public:
enum { Enum1, EnumWithLongName2 ...};
};
This is fine to express that these enums solely belong to that class. At times however I have a large list of these enums (e.g. in result lists for unit tests), which get very large when I have to qualify each enum with the class' name. Is there a way to add a shortcut in such cases so that I can omit the class name?
I looked at C++'s type alias, but that doesn't seem to help here. Other ideas?
Yes, there's one : a derived class inherits the enum names and can use them without further qualification.
So, create a helper class which inherits from ContainerClass to define the list. However, the helper class isn't intended to be instantiated (You wouldn't want to crate another ContainerClass base subobject) so define the list as a static member:
class enumList : public ContainerClass {
enumList() = delete;
public:
static decltype(Enum1) list[2] = { Enum1, EnumWithLongName2 };
};

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.

Factory Method and Cyclic Dependency

Edit: Thanks folks, now I see my mistake.
If I'm not wrong, because of its nature in factory method there is cyclic dependency:
Base class needs to know subclasses because it creates them, and subclasses need to know base class. Having cyclic dependency is bad programming practice, is not it?
Practically I implemented a factory, I have problem above, even I added
#ifndef MYCLASS_H
#define MYCLASS_H
#endif
I'm still getting
Compiler Error C2504 'class' : base class undefined
And this error disappers when I remove subclass include from base class header.
Solution 1: don't #include the derived class headers in the base class header, only in the base class cpp. The declaration of the factory method should not use the type of concrete classes returned, only the base type.
Solution 2: use a separate factory class (or a factory method within a separate class) to create your objects. Then the cyclic dependency is totally eliminated. This is the preferred way.
The factory shouldn't be a base class of the products.
Base classes never need to know about derived classes.
You need to revisit your pattern description, because I think you might be mixing a couple of different patterns together: if you're using it to create derived classes, then the factory shouldn't be part of the base class. If you're just using it to create various instances of a single class, then it could be a static member of that class.
In the error message you're getting above, the derived classes always need to know the full implementation of the base class. As a design matter, base classes should never know anything about derived classes.
struct Base {
Base * Create(int param);
};
struct Derived0 : public Base {
};
struct Derived1 : public Base {
};
Base * Base::Create(int param) {
switch (param) {
case 0: return new Derived0();
case 1: return new Derived1();
}
You should not try to implement the factory function within the Base class definition. Simply declare it there, and define it after the derived classes definitions.

Can you have protected nested classes in C++?

I have a class that only really ever needed by classes in a certain class hierarchy. I wanted to know if it is possible to nest the class in the highest class's protected section and have all the other classes automatically inherit it?
"Inherit" is the wrong word to use since it has a very specific definition in C++ which you don't mean, but yes you can do that. This is legal:
class A {
protected:
class Nested { };
};
class B : public A {
private:
Nested n;
};
And code that is not in A or something that derives from A cannot access or instantiate A::Nested.