i have Parent and Child classes. Child inherits from Parent. I want to store in a vector of Child objects the children of a parent object.
I include the Child header into the Parent header, but i have to include the Parent header into the Child header (since it inherits from Parent).
How do i overcome this circular inclusion?
Parent.h
#pragma once
#include <vector>
#include "Child.h"
using std::vector;
class Parent
{
public:
Parent();
~Parent();
vector<Child> children;
};
Parent.cpp
#include "stdafx.h"
#include "Parent.h"
Parent::Parent()
{
}
Parent::~Parent()
{
}
Child.h
#pragma once
#include "Parent.h"
class Child : Parent
{
public:
Child();
~Child();
};
Child.cpp
#include "stdafx.h"
#include "Child.h"
Child::Child()
{
}
Child::~Child()
{
}
Errors
child.h(4): error C2504: 'Parent' : base class undefined
parent.h(11): error C2065: 'Child' : undeclared identifier
Forward declare Child, and store pointer inside of vector.
Parent.h
#pragma once
#include <vector>
using std::vector;
class Child;
class Parent
{
public:
Parent();
~Parent();
vector<Child*> children;
};
Related
I am kind of new to C++ (and StackOverflow). I am trying to get something to work, but I have some #include problems.
I want to call a callback I made (from here), but I am struggling to do this.
This is my code so far. When I include child.hpp in the someclass.hpp file (because it needs information about Child for Callback<Child>), it has a looped include and the compiler crashes.
I have read about forward declarations (would be class Child; in the someclass.hpp file), and after trying I figured out this works, but I also read different opinions about this.
I have all .hpp files guarded with #ifndef CLASSNAME #define CLASSNAME ... #endif
Do I need to change my entire design, or what is the best option in my case?
base.hpp
#include "someclass.hpp"
class Base
{
protected:
unique_ptr<SomeClass> someClass;
};
base.cpp
#include "base.hpp"
Base::Base()
{
this->someClass = make_unique<SomeClass>();
}
child.hpp
#include "base.hpp"
class Child : public Base
{
public:
void callbackFunction(std::string data);
unique_ptr<Callback<Child>> callback;
};
child.cpp
#include "child.hpp"
void Child::callbackFunction(std::string data)
{
/*does something*/
}
Child::Child()
{
this->callback = make_unique<Callback<Child>>(this, &Child::callbackFunction);
//I can call this->callback->call(data); here without problems
this->someClass->setCallback(this->callback);
//^^^^^^^^^^^^^^^ == base.someClass
}
someclass.hpp
#include "child.hpp" // < does crash compiler due to loop
//> someclass.hpp uses child.hpp
//> child.hpp uses base.hpp
//> base.hpp uses someclass.hpp
// and thus loop
class SomeClass
{
public:
void someFunction(std::string data);
void setCallback(unique_ptr<Callback<Child>> callback);
unique_ptr<Callback<Child>> callbackInstance;
};
someclass.cpp
//not 100% sure about the type of this parameter
void setCallback(unique_ptr<Callback<Child>> callback)
{
this->callbackInstance = callback;
}
void SomeClass::someFunction(std::string data)
{
//here I want to call this "Child::callbackFunction" which should go like "this->callbackInstance->call(data)" ?
}
also in someclass.hpp
template<class T>
class Callback
{
public:
Callback(T* instance, void (T::*function)(std::string))
{
this->callbackInstance = instance;
this->callback = function;
}
void call(std::string data)
{
(callbackInstance->*callback)(data);
}
private:
T *callbackInstance;
void (T::*callback)(std::string);
};
To solve the mentioned error("expected class-name before '{' token on child.hpp") you should remove the #include "someclass.hpp" from base.hpp and replace it with a forward declaration for class SomeClass as shown below.
base.hpp
#ifndef BASE_H
#define BASE_H
//NO NEED TO INCLUDE someclass.hpp
#include <memory>
class SomeClass;//FORWARD DECLARE SomeClass
class Base
{
std::unique_ptr<SomeClass> someClass;
public:
//add declaration for default constructor
Base();
};
#endif
base.cpp
#include "base.hpp"
#include "someclass.hpp"
//other things here
Base::Base()
{
this->someClass = std::make_unique<SomeClass>();
}
child.hpp
#ifndef CHILD_H
#define CHILD_H
#include "base.hpp"
#include <memory>
#include "someclass.hpp"
class Child : public Base
{
public:
void callbackFunction(std::string data);
std::unique_ptr<Callback<Child>> callback;
//add declaration for default constrcutor
Child();
};
#endif
child.cpp
#include "child.hpp"
void Child::callbackFunction(std::string data){
/*does something*/
}
Child::Child()
{
this->callback = std::make_unique<Callback<Child>>(this, &Child::callbackFunction);
//I can call this->callback->call(data); here without problems
}
someclass.hpp
#ifndef SOMECLASS_H
#define SOMECLASS_H
#include <string>
//REMOVED include child.hpp from here
class SomeClass
{
public:
void someFunction(std::string data);
//I think I need an instance of Callback<Child> here?
};
template<class T>
class Callback
{
public:
Callback(T* instance, void (T::*function)(std::string))
{
this->callbackInstance = instance;
this->callback = function;
}
void call(std::string data)
{
(callbackInstance->*callback)(data);
}
private:
T *callbackInstance;
void (T::*callback)(std::string);
};
#endif
someclass.cpp
#include "someclass.hpp"
void SomeClass::someFunction(std::string data)
{
//here I want to call this "Child::callbackFunction" which should go like "this->callbackInstance->call(data)" ?
}
The above program compiles and executes successfully as can be seen here.
Summary
Some of the changes that i made are listed below:
Removed unnecessary includes
Added declarations for default constructor in child.hpp and base.hpp
Added include guards in all headers.
This question already has answers here:
What are forward declarations in C++?
(8 answers)
Closed 3 years ago.
I'm currently going through the "Qt for Beginners" on https://wiki.qt.io and have come across this header and source. In the header, there is an empty class called "QPushButton".
windows.h
#ifndef WINDOW_H
#define WINDOW_H
#include <QWidget>
class QPushButton; // Empty Class
class Window : public QWidget
{
...
private:
QPushButton *m_button;
...
};
window.cpp
#include "window.h"
#include <QPushButton>
Window::Window(QWidget *parent) : QWidget(parent)
{
...
m_button = newQPushButton("Hello World", this);
...
}
My question is, would it be better to put a #include inside the header file rather than create an empty class, and remove #include in the source file altogether? It compiles and runs the same.
Like this:
windows.h
#ifndef WINDOW_H
#define WINDOW_H
#include <QWidget>
#include <QPushButton> // Added new include directive
// Removed QPushButton Class
class Window : public QWidget
{
...
private:
QPushButton *m_button;
...
};
window.cpp
#include "window.h"
// Removed include directive for QPushButton
Window::Window(QWidget *parent) : QWidget(parent)
{
...
m_button = newQPushButton("Hello World", this);
...
}
If not, please explain. Thanks!
It's not an empty class, it's just a forward declaration to tell the compiler there will be a definition appearing later on. It's usually to get around this situation:
class Parent
{
Child* pChild; ///< error, child undefined!
};
class Child
{
Parent* pParent; ///< all good, Parent has been defined.
};
When this happens, you can add a forward declaration for Child like so:
// forward declare class to avoid compiler error
class Child;
class Parent
{
Child* pChild; ///< Now we are all good
};
class Child
{
Parent* pParent;
};
Currently, I am working on c++ project I want to know how I can send an instance of a child class to function use parent as a parameter and execute a function in a child here is an example: I want Child print function to be called
Parent.h
#ifndef UNTITLED_PARENT_H
#define UNTITLED_PARENT_H
class Parent {
public:
virtual void printData();
};
#endif
Parent.cpp
#include "Parent.h"
#include <iostream>
using namespace std;
void Parent::printData() {
cout<<"Parent"<<endl;
}
Child.h
#ifndef UNTITLED_CHILD_H
#define UNTITLED_CHILD_H
#include "Parent.h"
class Child : public Parent{
public:
void printData();
};
#endif
Child.cpp
#include "Child.h"
#include <iostream>
using namespace std;
void Child::printData() {
cout<<"Child"<<endl;
}
ParentUser.h
#ifndef UNTITLED_PARENTUSER_H
#define UNTITLED_PARENTUSER_H
#include "Parent.h"
class ParentUser {
public:
void printer(Parent p);
};
#endif
ParentUser.cpp
#include "ParentUser.h"
void ParentUser::printer(Parent p) {
p.printData();
}
main.cpp
#include <iostream>
#include "Parent.h"
#include "Child.h"
#include "ParentUser.h"
int main() {
Child child;
ParentUser parentUser;
parentUser.printer(child);
return 0;
}
Your function void printer(Parent p); will create a new object of type Parent using a copy constructor your compiler automagically creates for you. You need to change it to take a reference instead:
void printer(Parent& p);
This will make sure that p is actually a reference to child, not a new Parent created from child using a copy constructor.
What's happening here is also called object slicing, as the copy is a parent type, which does not have any of the members defined in the child class.
WTL is template library, so i have to implement it in template library header file.
I want to implement my logic in .cpp file otherwise, i will have to code a huge header file.
for example, in MainFrm.h
// ...
// MainFrm.h
class CMainFrame :
public CFrameWindowImpl<CMainFrame>,
public CUpdateUI<CMainFrame>,
public CMessageFilter, public CIdleHandler
{
//...
void function1()
{
//...
}
void function2()
{
//...
}
}
I want to have function1() and function2() in myfunction.cpp, how to do it?
Please guide.
EDIT:
Solved! thanks to Jan S. i had include myfunction.cpp into WTL project and add some lines:
MainFrm.h:
// ...
// MainFrm.h
#if 1
#include <atlframe.h>
#include <atlsplit.h>
#include <atlctrls.h>
#include <atlctrlw.h>
#include <atlctrlx.h>
#include "sampleView.h"
#include "resource.h"
#endif
// MainFrm.h
class CMainFrame :
public CFrameWindowImpl<CMainFrame>,
public CUpdateUI<CMainFrame>,
public CMessageFilter, public CIdleHandler
{
//...
void functionx();
//...
};
myfunction.cpp:
// myfunction.cpp
#include "stdafx.h"
#include "MainFrm.h"
void CMainFrame::functionx()
{
//...
}
In your header put the declaration
// MainFrm.h
class CMainFrame :
public CFrameWindowImpl<CMainFrame>,
public CUpdateUI<CMainFrame>,
public CMessageFilter, public CIdleHandler
{
//...
void functionx();
//...
};
In your .cpp file put the definition
#include MainFrm.h
void CMainFrame::functionx()
{
// more code
}
The compiler errors
You seem to be missing WTL header includes
#include <atlframe.h>
#include <atlsplit.h>
Off topic but, in your header make sure you have
#pragma once
or
#ifndef UNIQUE_HEADER_NAME
#define UNIQUE_HEADER_NAME
//header code
#endif
This will stop duplicate declarations.
It's the follow up question of this: error C2504 circular inclusion.
Child if forward declared in parent's header.
It is not included, so the complier wont find Child? Then how do i instantiate a new Child object from Parent object.
Parent.h
#pragma once
#include <vector>
using std::vector;
class Child;
class Parent
{
public:
Parent();
void GiveBirth();
~Parent();
vector<Child*> children;
};
Parent.cpp
#include "stdafx.h"
#include "Parent.h"
Parent::Parent()
{
}
void Parent::GiveBirth()
{
Child ch = Child(); //Error: incomplete type is not allowed
}
Parent::~Parent()
{
}
Child.h
#pragma once
#include "Parent.h"
class Child : Parent
{
public:
Child();
~Child();
};
Child.cpp
#include "stdafx.h"
#include "Child.h"
Child::Child()
{
}
Child::~Child()
{
}
Here are some reading list for you.
http://en.wikipedia.org/wiki/Opaque_pointer
http://en.wikibooks.org/wiki/C%2B%2B_Programming/Idioms#Pointer_To_Implementation_.28pImpl.29
Parent.cpp
#include "stdafx.h"
#include "Parent.h"
#include "Child.h"
Parent::Parent()
{
}
void Parent::GiveBirth()
{
//Child ch = Child(); //Error: incomplete type is not allowed
children.push_back(new Child());
}
Parent::~Parent()
{
}