//Parent.h
class Parent{
public:
Parent(){}
~Parent(){}
virtual void func1() = 0;
};
//Child.h
#include "Parent.h"
class Child : public Parent{
int x, y;
public:
Child() : Parent(){ //constructor
}
virtual void func1();
};
//Child.cpp
#include "Child.h"
void Child::Parent::func1(){
}
This compiles fine, however, I want to put the implementation of the constructor (and destructor) of Child class in its cpp file, is it possible? How?
I've tried the code below but it throws undefined reference to vtable for Child
Child::Child() : Parent(){ //in the cpp
}
Child(); //in the header file
Child():Parent(); //also tried this one
A couple of things for you to do:
Guard-post your header files to prevent unintended multiple inclusion.
Make your Parent destructor virtual
Initialize your non-auto member variables to determinate values.
Your final layout can look something like this.
Parent.h
#ifndef PARENT_H_
#define PARENT_H_
class Parent
{
public:
Parent() {};
virtual ~Parent() {};
public:
virtual void func1() = 0;
};
#endif // PARENT_H_
Child.h
#ifndef CHILD_H_
#define CHILD_H_
#include "Parent.h"
class Child : public Parent
{
int x,y;
public:
Child();
virtual ~Child();
virtual void func1();
};
#endif
Child.cpp
Child::Child()
: Parent() // optional if default
, x(0), y(0) // always initialize members to determinate values
{
}
Child::~Child()
{
}
void Child::func1()
{
}
$ cat Parent.h
#ifndef GUARD_PARENT_H_
#define GUARD_PARENT_H_
class Parent{
public:
Parent(){}
~Parent(){}
virtual void func1() = 0;
};
#endif /* GUARD_PARENT_H_ */
$ cat Child.h
#ifndef GUARD_CHILD_H_
#define GUARD_CHILD_H_
#include "Parent.h"
class Child : public Parent{
int x, y;
public:
Child();
virtual void func1();
};
#endif /* GUARD_CHILD_H_ */
$ cat Child.cpp
#include "Child.h"
Child::Child() : Parent() {
}
void Child::func1(){
}
$ cat try.cc
#include "Child.h"
int main() {
Child c;
}
$ g++ try.cc Child.cpp
$ ./a.out
$
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.
i am new to c++ programming and now faceing this "simple" problem for a while. I am implementing a simple step of a Observer-Pattern with the classes: Observer and Observable.
#ifndef OBSERVER_H
#define OBSERVER_H
#include "observable.h"
class Observer{
public:
virtual ~Observer() = default;
virtual void update(Observable* obs ) = 0;
};
#endif // OBSERVER_H
the Observabel Class Looks like that:
#ifndef OBSERVABLE_H
#define OBSERVABLE_H
#include <vector>
#include "observer.h"
class Observable
{
public:
Observable();
virtual ~Observable() = default;
void attach(Observer &o);
void detach(Observer &o);
void notify();
private:
std::vector<Observer*> observerlist;
};
#endif // OBSERVABLE_H
c++- file
#include "observable.h"
#include <algorithm>
void Observable::attach(Observer &o) { observerlist.push_back(&o); }
void Observable::detach(Observer &o)
{
observerlist.erase(std::remove(observerlist.begin(), observerlist.end(), &o));
}
void Observable::notify()
{
for (Observer* obs : observerlist) {
obs->update(this); // Here the IDE Shows the Error
}
}
Error:
C:\U...\observable.cpp:16: error: C2660: "Observer::update": function does not take 1 Argument
I really hope one of you can help.
greetings
I have a question again:
I have a class PBV t(inherits from Tab) hat has a class Geometry. Geometry is the parent of Geo_1. From Geo_1 I want to have access to methods of PBV ( e.g. printContent . How do I do that? I am able to create Signal-Slots but since I have to use methods of PBV often that would make lots of Signal-Slots.
Here is my code:
PBV.h:
#include "../Geometry/Geo_1.h"
class PBV : public Tab
{
Q_OBJECT
public:
explicit PBV (QWidget *parent = 0);
~ PBV ();
virtual void printContent( QStringList *const qsl);
private:
Geo_1 *GEO_1;
Geometry *GEO;
}
PBV.cpp:
…
Geo_1 *GEO_1;
GEO_1 = new Geo_1(this);
GEO_1->set_LNE_default();
…
.
Geo_1.h:
#ifndef GEO_1_H
#define GEO_1_H
#include "Geometry.h"
#include "../Tabs/PBV.h"
class Geo_1: public Geometry
{
Q_OBJECT
public:
Geo_1 (QObject *_parent = 0);
virtual void set_LNE_default();
};
#endif // GEO_1_H
.
Geo_1.cpp:
#include "Geometry.h"
#include <QDebug>
#include "Geo_1.h"
#include "../Tabs/PBV.h"
Geo_1::Geo_1(QObject*_parent)
: Geometry(_parent) {}
void Geo_1::set_LNE_default()
{
// here I want to use printContent
}
.
Geometry.h:
#ifndef GEOMETRY_H
#define GEOMETRY_H
#include <QObject>
class Geometry : public QObject
{
Q_OBJECT
public:
Geometry(QObject *_parent=0);
~Geometry();
virtual void set_LNE_default();
};
#endif // GEOMETRY_H
.
Geometry.cpp:
#include "Geometry.h"
#include <QDebug>
Geometry::Geometry(QObject *_parent)
: QObject(_parent) {}
Geometry::~Geometry(){}
void Geometry::set_LNE_default() { }
One approach, as referred to by comments, is to keep track of the parent class in the constructor of the child:
In Geometry.h, add a private member variable:
private:
PBV* m_pParentPBV;
Then, in the constructor in Geometry.cpp, set this to the parent you are already passing:
Geometry::Geometry(QObject *_parent)
: QObject(_parent)
{
m_pParentPBV = dynamic_cast<PBV*>(_parent);
}
Now you can call methods on the parent using m_pParentPBV->printContent() etc.
I have main executable and two functions that are dereferenced to DLL.
class CPluginInterface
{
public:
virtual void A(void) = 0;
virtual void B(void) = 0;
};
I created DLL like this
//Main.h
#include "Function.h"
class CForward : public CPluginInterface
{
public:
//void A(void);
void B(void);
};
//Main.cpp
#include "Main.h"
/*void CForward::A(void)
{
//A Function is commented because it is not used
}*/
void CForward::B(void)
{
//Do something here
}
extern "C"
{
// Plugin factory function
//void __declspec(dllexport) __cdecl A(void) { }
void __declspec(dllexport) __cdecl B(void) { }
}
However the program is crashed because A(void) doesn't exist when the main executable dereferencing it. How to skip A(void)?
If I create the DLL like this, it works fine.
//Main.h
#include "Function.h"
class CForward : public CPluginInterface
{
public:
void A(void);
void B(void);
};
//Main.cpp
#include "Main.h"
void CForward::A(void)
{
//Do something here
}
void CForward::B(void)
{
//Do something here
}
extern "C"
{
// Plugin factory function
void __declspec(dllexport) __cdecl A(void) { }
void __declspec(dllexport) __cdecl B(void) { }
}
NB: I create Plugin Interface.
The =0 suffix on your interface's virtual functions indicate that they are pure virtual and that you are required to override them when inheriting from the base class. In your first example CForward is an abstract class because you have not overridden A, thus you cannot create an instance of CForward.
https://stackoverflow.com/a/2652223
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()
{
}