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.
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 want to create some objects that can delegate some work to its nested subobjects, but it pushes me into the circular dependency issues. Using of #ifndef directive works fine if I have only two classes (ClassA and ClassB), but this pattern doesn't work when ClassC is added. Is it possible to achieve such type of structure as shown in the code below and don't get an "undefined type" errors?
ClassA.h
#pragma once
#include "CoreMinimal.h"
#include "ClassB.h"
class UClassB;
#include ClassA.generated.h
UCLASS()
class PROJ_API UClassA : public UObject
{
GENERATED_BODY()
UPROPERTY()
UClassB* ObjB;
public:
void DoDelegation()
{
auto* ThisInstance = this;
ObjB = NewObject<UClassB>();
ObjB->DoWorkClassB(ThisInstance);
}
}
ClassB.h
#pragma once
#include "CoreMinimal.h"
//works nice
#ifndef CLASSA_H
#define CLASSA_H
#include "ClassA.h"
class UClassA;
#endif
//trying to use similar pattern which works with ClassA.h and ClassB.h
#include "ClassC.h"
class UClassC;
#include ClassB.generated.h
UCLASS()
class PROJ_API UClassB : public UObject
{
GENERATED_BODY()
UPROPERTY()
UClassC* ObjC;
public:
void DoDelegation()
{
auto* ThisInstance = this;
ObjC = NewObject<UClassC>();
ObjC->DoWorkClassC(ThisInstance);
}
void DoWorkClassB(UClassA* &ObjectClassA)
{
// do some stuff with ObjectClassA
}
}
ClassC.h
#pragma once
#include "CoreMinimal.h"
//trying to use similar pattern which works with ClassA.h and ClassB.h
//got "undefined type" error
#ifndef CLASSB_H
#define CLASSB_H
#include "ClassB.h"
class UClassB;
#endif
#include ClassC.generated.h
UCLASS()
class PROJ_API UClassC : public UObject
{
GENERATED_BODY()
public:
void DoWorkClassC(UClassB* &ObjectClassB)
{
// do some stuff with ObjectClassB
}
}
creating classes that refer to each other
Is it possible to achieve such type of structure as shown in the code below and don't get an "undefined type" errors?
Certainly. Referring to an object (with a pointer for example) of some class only requires declaration of the other class, not definition.
Simple solution is to declare both classes before defining either of them.
It's still not fully clear for me, but at least i understood why forward declaration wasn't worked for the first time. Inline implementation of methods that do something with such referencing classes is strictly not recommended. It compiles well If function is implemented in cpp.
I have a Cpp Class which I want to refactor into a header and .cpp file. No problem normally, but when I try to do this Qt Quick one I can't get it to compile. It's fine if I put all of it in the header file, but otherwise I get various different errors depending on how I try to do it. Is there a proper way. I think it has to do with the Q_INVOKABLE bit, but not sure.
Here is my code...
#ifndef APPLICATIONDATA_H
#define APPLICATIONDATA_H
#include <QDateTime>
#include <QObject>
class ApplicationData : public QObject
{
Q_OBJECT
public:
ApplicationData(){}
Q_INVOKABLE QDateTime getCurrentDateTime() const{
return QDateTime::currentDateTime();
}
};
#endif // APPLICATIONDATA_H
Thanks for any pointers.
This compiles but I'm not sure why it does or why it didn't:
//header file
#ifndef APPLICATIONDATA_H
#define APPLICATIONDATA_H
#include <QDateTime>
#include <QObject>
class ApplicationData : public QObject
{
Q_OBJECT
public:
ApplicationData(); //constructor
Q_INVOKABLE QDateTime getCurrentDateTime() const; //function
};
#endif // APPLICATIONDATA_H
//.cpp file
#include "applicationdata.h"
#include <QDateTime>
#include <QObject>
ApplicationData::ApplicationData(){} //constructor implementation
QDateTime ApplicationData::getCurrentDateTime() const{ //function implementation
return QDateTime::currentDateTime();
}
I have a parametrized class Queue and a subclass ClientsQueue not parametrized that inherits from Queue. I think I have a syntax error:
client.h
#ifndef CLIENT_H_
#define CLIENT_H_
class Client {
public:
Client();
~Client();
};
#endif
queue.h
#ifndef QUEUE_H_
#define QUEUE_H_
template <class T> class Queue {
public:
Queue();
~Queue();
};
#endif
clientsQueue.h
#ifndef CLIENTSQUEUE_H_
#define CLIENTSQUEUE_H_
#include "queue.h"
#include "client.h"
class ClientsQueue: public Queue<Client> {
public:
ClientsQueue();
~ClientsQueue();
};
#endif
clientsQueue.cpp
#include "clientsQueue.h"
ClientsQueue::ClientsQueue() {
};
bank.cpp
#include "clientsQueue.cpp"
int main() {
return 0;
}
So, when I try to compile and run the program, the compiler says:
clientsQueue.cpp:3:1: error: ‘ClientsQueue’ does not name a type
ClientsQueue::ClientsQueue() {
^
I can't see the error. If I quit all the code from clientsQueue.cpp, it works.
How can I fix it?
Thanks!
You should #include "clientsQueue.h" not #include "clientsQueue.cpp" in main file. When you include header you present a declarations to the compiler. You miss the declaration of the class ClientsQueue when you include just the source (cpp) file.
I have a bit of code of the following format contained in a single .h and .cc file:
myClass.h:
#ifndef MYCLASS_H
#define MYCLASS_H
class myClass
{
public:
myClass(); // constructor
~myClass(); // destructor
void classMethod1 ();
void classMethod2 ();
int memberVarable1;
int memberVariable2;
};
#endif
and myClass.cc:
#include "myClass.h"
myClass::myClass(){
// stuff
}
myClass::~myClass(){
// stuff
}
void myClass::classMethod1 (){
// stuff
}
void myClass::classMethod2 (){
// stuff
}
All of this is working fine. However my project is getting quite large and I'm about to add a set of new functionality. Instead of clogging up myClass.h and myClass.cc I want to put some new methods in another .cc file. I don't seem to be able to get this to work though.
myClass.h:
#ifndef MYCLASS_H
#define MYCLASS_H
#include "secondFile.h"
class myClass
{
public:
myClass(); // constructor
~myClass(); // destructor
void classMethod1 ();
void classMethod2 ();
int memberVarable1;
int memberVariable2;
};
#endif
and myClass.cc:
#include "myClass.h"
#include "secondFile.h"
myClass::myClass(){
// stuff
}
myClass::~myClass(){
// stuff
}
void myClass::classMethod1 (){
// stuff
}
void myClass::classMethod2 (){
// stuff
}
secondFile.h:
#ifndef SECONDFILE_H
#define SECONDFILE_H
void someNewMethod();
#endif
secondFile.cc
#include "secondFile.h"
void someNewMethod(){
// can't see classMethod1()
}
In every source file, you need to include every header file that declares functions, etc. you want to use.
So in your case, it seems like you want secondFile.cc to contain
#include "myClass.h"
#include "secondFile.h"
void someNewMethod(){
// can't see classMethod1()
}
Btw, what you are doing is quite common to do in practice. Sometimes, I go even further than what you suggest, and implement the various methods of a single class in multiple source files. For large, complicated classes, this helps speed up the development cycle because I only have to recompile a fraction of the class implementation if I only made a small change. Example:
myclass.h
#pragma once
class MyClass
{
...
void complicatedMethod0();
void complicatedMethod1();
...
};
myclass_impl0.cpp
#include "myclass.h"
void MyClass::complicatedMethod0()
{
...
}
myclass_impl1.cpp
#include "myclass.h"
void MyCLass::complicatedMethod1()
{
...
}
If you are intending to add methods to myClass, you can't do that - the class methods have to be contained in one definition.
You can extend myClass, however, by inheriting from it:
secondFile.h:
#ifndef SECONDFILE_H
#define SECONDFILE_H
#include "myClass.h"
class mySecondClass : public myClass
{
public:
void someNewMethod();
}
#endif
secondFile.cc
#include "secondFile.h"
void mySecondClass::someNewMethod(){
this.classMethod1();
}
#include "secondFile.h"
#include "myClass.h"
//if you want the class methods,
//you need to tell the compiler where to look
void someNewMethod(){
// can't see classMethod1()
}
it seems you've forgotten to include "myClass.h".