In C++, How to Forward Declare a Class as Inheriting from Another Class

In C++, is it possible to forward declare a class as inheriting from another class?

A forward declaration is only really useful for telling the compiler that a class with that name does exist and will be declared and defined elsewhere. You can't use it in any case where the compiler needs contextual information about the class, nor is it of any use to the compiler to tell it only a little bit about the class. (Generally, you can only use the forward declaration when referring to that class without other context, e.g. as a parameter or return value.)

Thus, you can't forward declare Bar in any scenario where you then use it to help declare Foo, and it flat-out doesn't make sense to have a forward declaration that includes the base class -- what does that tell you besides nothing?

forward declaring with inheritance information

This should work. You need to move other up

BUT declare func below. That way func is able to "see" that derived is of type base.

e.g.,

class base;
class derived;
//class derived : public base;

class other
{
public:
void func();
base* base1;
derived* derived1;
};

class base {};
class derived : public base {};

void other::func() { base1 = derived1; }

Forward declaration of inherit class

The easiest would be to separate the class from the implementation: first declare all the classes. Then only the implementation of the member functions.

class Status;
class Door {
...
};
class Status {
...
};

class Open : public Status {
public:
void opendoor(Door* s) override;
void closedoor(Door* s) override;
};

class Close : public Status {
public:
void opendoor(Door* s) override;
void closedoor(Door* s) override;
};
...
void Open::closedoor(Door* s){
s->setStatus( new Close() ); //no more error here
return;
}

Forward Declaration of a Base Class

The first problem you can't solve.

The second problem is not anything to do with standard library classes. It's because you declare an instance of the class as a member of your own class.

Both problems are due to the requirement that the compiler must be able to find out the total size of a class from its definition.

However, the compiler can work out the size of a pointer to a class, even if it doesn't yet have the full definition of it. So a possible solution in such cases is to have a pointer (or reference) member in the consuming class.

Not much help in the base class case, because you won't get an 'is a' relationship.

Nor is it worth doing for something like std::string. Firstly, it's supposed to be a convenient wrapper around a character buffer, to save you from doing memory management on something so simple. If you then hold a pointer to it, just to avoid including the header, you're probably taking a good idea too far.

Secondly (as pointed out in a comment), std::string is a typedef to std::basic_string<char>. So you need to forward declare (and then use) that instead, by which time things are getting very obscure and hard to read, which is another kind of cost. Is it really worth it?

Does a derived class inherit the forward declarations used by the base class?

Because there is absolutely no connection between class Data and class Node whatsoever, other than they happen to be in the same header file.

Header files are to make sharing declarations easy, but they exist entirely for your convenience. They have no effects whatsoever on the code contained in them. Let me see if I can clarify with an example:

apple.h

class Data;

class Node
{
public:
Node(){}
virtual ~Node(){}
virtual Node* Insert(Data *

banana.h

theData) = 0;
virtual void Show() = 0;
};

class TailNode : public Node
{
public:
TailNode(){}
~TailNode(){}
virtual Node* Insert(Data *theData);
virtual void Show() { }
};

mycode.cpp

#include "apple.h"
#include "banana.h"

int main() {
}

The #include inside mycode.cpp effectively copy-pastes whatever is in that file into mycode.cpp. Since the copy-pasted code is valid:

class Data;

class Node
{
public:
Node(){}
virtual ~Node(){}
virtual Node* Insert(Data *theData) = 0;
virtual void Show() = 0;
};

class TailNode : public Node
{
public:
TailNode(){}
~TailNode(){}
virtual Node* Insert(Data *theData);
virtual void Show() { }
};

int main() {
}

Then the program is valid, and works fine!

How to derive from incomplete class in C++

If you have forward declarations, then you usually do not need to include the specified header.

Context.h should NOT include A.h, nor apparently should A.h include Context.h.

Since B actually uses the A class directly (you cannot derived from an incomplete class), it will need to include A.h.

Code in Context:

#pragma once

class A; //pointers do not require an include

class Context {
...
A* someMethod();

};

Code in A:

#pragma once

class Context; //pointers do not require an include

class A {
...
Context* someOtherMethod();
...
};

Code in B:

#pragma once
#include "A.h" //inheritance requires include

class B : public A {
A* method(Context* context) { ... };
};

C++ forward declare class constructor with initialization list

In the MyDerivedClass you want to call the MyBaseClass constructor, not declare it, so just pass the arguments down, don't try to declare them. So remove the int before arg1 and arg2.

class MyDerivedClass : public MyBaseClass {
public:
MyDerivedClass(int arg1, int arg2, int arg3) : MyBaseClass(arg1, arg2) {
// implementation here
}
};

If you want to move the MyDerivedClass constructor to a cpp file, then put this into the header:

class MyDerivedClass : public MyBaseClass {
public:
MyDerivedClass(int arg1, int arg2, int arg3);
};

and this into the cpp file:

MyDerivedClass::MyDerivedClass(int arg1, int arg2, int arg3)
: MyBaseClass(arg1, arg2)
{
}

Forward declaration with Inheritance and include | incomplete type or expected class name

The includes are all goofed up.

Delete the superfluous include directives from the files where they are irrelevant.

Add include directives on the files where they are depended upon.

Room.h

#ifndef ROOM_H
#define ROOM_H

/* DELETE: because Room.h does not depend on it.
#include "Console.h"
*/

// ...

class Room {
public:
void room();
};

#endif // ROOM_H

Room.cpp

#include "Room.h"

/* ADD: because Room.cpp does depend on it. */
#include "Console.h"

void Room::room() {
Console::print();
}

Console.h

#ifndef CONSOLE_H
#define CONSOLE_H

/* DELETE: because Console.h does not depend on them.
#include "Room.h"
#include "RoomChild.h"
*/

class Console {
public:
static void print();
};

#endif // CONSOLE_H

Console.cpp

#include "Console.h"

void Console::print() {
;
}

RoomChild.h

#ifndef ROOM_CHILD_H
#define ROOM_CHILD_H

#include "Room.h"
/* DELETE: because RoomChild.h does not depend on it
#include "Console.h"
*/

class RoomChild : public Room {
public:
void roomChild();
};

#endif // ROOM_CHILD_H

RoomChild.cpp

#include "RoomChild.h"
/* ADD: because RoomChild.cpp does depend on it. */
#include "Console.h"

void RoomChild::roomChild() {
Console::print();
}


Related Topics



Leave a reply



Submit