The situation is like this:
//header file
#ifndef CLASSA_H
#define CLASSA_H
#include <stdint.h>
class ClassA
{
public:
void function1();
void function2();
};
#endif //CLASSA_H
//cpp file
#include "ClassA.h"
void ClassA::function1()
{
/* some code */
}
void ClassA::function2()
{
/* some more code */
}
void function3()
{
/* more code /*
}
//main.cpp
#include "ClassA.h"
int main()
{
ClassA obj;
obj.function3();
}
I want to call function3() in main.cpp but without inheritance. I tried using the instance of ClassA but that says "function3 is not a member of classA".
Maybe I'm missing a concept, would be great if anyone can help.
When you try to call function3() with obj.function3() syntax, the compiler then tries to find if there's a function exists named function3 in the instance of the class (i.e. object).
Now, in this case, you can do two things:
Include void function3() in the public: of the class and change void function3() to void ClassA :: function3() to tell the compiler that the containing code is defined for the class member function.
Or, define the function inside the header file and prevent calling the function by defining the class object. It's obvious, isnce you can't access something which is declared outside of the class.
The code explanation of all the two above methods is as follows:
Method 1
ClassA.cpp
#include "ClassA.h"
...
void ClassA::function3() // definition of the class member function
{
/* more code */
}
main.cpp
#include "ClassA.h"
int main()
{
ClassA obj;
obj.function3(); // now it's inside the class member function
// hence, we may now use it
}
ClassA.h
...
class ClassA
{
public:
...
void function3(); // declared inside the class
};
#endif //CLASSA_H
Method 2
ClassA.h
...
void function3()
{
/* more code */
}
main.cpp
#include "ClassA.h"
int main()
{
function3();
}
ClassA.cpp
class {
...
};
void function3()
{
/* more code */
}
But the second method will make the class useless, therefore, possibly you meant to achieve the first method and not the second.
Related
I got two classes separated in four files. The main class includes a sub class and needs to execute functions of it (not shown in the minimal example code). What I want to do is to execute a function of the main class in the scope of the subclass.
I think some ideas would be to inherit the functions in the sub class but I could not figure out how to do this.
MainClass.cpp
#include "MainClass.hpp"
void MainClass::mainCallback() {
std::cout << "[mainCallback] executed" << std::endl;
}
void MainClass::subCallback() {
std::cout << "[subCallback] executed" << std::endl;
}
int main() {
MainClass mainClass;
mainClass.mainCallback();
SubClass subClass;
subClass.activateSubClass();
return 0;
}
MainClass.hpp
#pragma once
#include "SubClass.hpp"
#include <iostream>
class MainClass{
public:
void mainCallback();
void subCallback();
};
SubClass.cpp
#include "SubClass.hpp"
void SubClass::activateSubClass(){
mainClass.subCallback(); //TODO call this function from this scope
}
SubClass.hpp
#pragma once
class SubClass{
public:
void activateSubClass();
};
The error in SubClass.cpp is of course:
error: use of undeclared identifier 'mainClass'
Just subclass the subclass:
class SubClass: public MainClass {
public:
void activateSubClass();
};
This (public) way the SubClass makes all methods of MainClass callable in SubClass instances. You could also private inherit. That way only activateSubClass() 'ld be callable.
In activateSubClass you can call directly the methods of the parent class:
void SubClass::activateSubClass(){
mainClass.subCallback(); //TODO call this function from this scope
}
Don't forget to include MainClass.hpp in SubClass.hpp
You try to call a MainClass.subCallback() without having an instance of MainClass. According to me, this is the typical use case for static methods.
Then, I think you make your #include directives the wrong way. Indeed, MainClass does not seem to need to know SubClass but the opposite is true. I think it is better to include MainClass.hpp in SubClass.hpp. This will solve your circle dependencies problem.And you can write your main() function in another file.
EDIT: Example
MainClass.hpp:
#pragma once
class MainClass
{
public:
void mainCallback();
static void subCallback(); // mak it static to be able to call it without an instance of the class
};
MainClass.cpp:
#include "MainClass.hpp"
#include <iostream>
void MainClass::mainCallback()
{
std::cout << "[mainCallback] executed" << std::endl;
}
void MainClass::subCallback()
{
std::cout << "[subCallback] executed" << std::endl;
}
SubClass.hpp:
#pragma once
class SubClass
{
public:
void activateSubClass();
};
SubClass.cpp:
#include "SubClass.hpp"
#include "MainClass.hpp" // MainClass inclusion
void Suclass::activateSubClass()
{
MainClass::subCallback(); // Call of the static method
}
main.cpp:
#include "MainClass.hpp"
#include "SubClass.hpp"
int main()
{
MainClass mc;
mc.mainCallback();
SubClass sc;
sc.activateSubClass(); // Will call MainClass::subCallback()
return 0;
}
I hope it can help you.
#ifndef CLASSB
#define CLASSB
#include "ClassA.h"
namespace name {
class ClassB
{
public:
static Handle conn();
};
}
#endif
-
#include "ClassB.h"
Handle name::ClassB::conn()
{
return getHandle(ClassA::it().str());
}
-
#ifndef CLASSA
#define CLASSA
#include "ClassB.h"
namespace name {
class ClassA
{
public:
template <typename T>
T myFunc(const std::string&)
{
auto tmp = ClassB::conn();
}
};
}
#endif
Calling ClassB::conn() gives a compiler error which says that the class ClassB is not declared. When I forward declare it I get an error message about an incomplete type.
I can't move the template function to my .cpp files as it is a template function. So, how to fix this?
Just remove #include "ClassA.h" from class B's header and it should work. But there appear to be multiple compilation problems with your code so it's hard to say (missing function getHandle, missing it(), missing type Handle etc).
Trying to pass a parent class object to a child class object so that the child class object has control over the parent class object's methods.
This is however resulting in header related issues.
I've tried forward declaring one of the classes but it seems whatever class is declared first always has trouble reading from the class declared below.
Both errors refer to Device' constructor where try to call dm's hello world method, they are:
Use of undefined type 'DeviceManager'
Left of '->HelloWorld' must point to class/struct/union/generic type
...
//main.cpp
#include "parent.h"
void main()
{
cout << "Created DeviceManager\n";
DeviceManager* deviceManager = 0;
deviceManager = new DeviceManager;
cout << "Giving DeviceManager a device\n";
deviceManager->p = new Device(deviceManager);
cout << "Giving Device a reference to DevicenManager\n";
deviceManager->Share();
}
...
class DeviceManager;
class Device
{
public:
Device(DeviceManager* manager)
{
dm = 0;
this->dm = manager;
this->dm->HelloWorld();
}
DeviceManager* dm;
};
//device manager
class DeviceManager
{
public:
DeviceManager()
{
p = 0;
}
void HelloWorld()
{
//if this calls we know the child has control over the parent.
cout << "Hello World";
}
Device* p;
};
Yes.
To solve circular dependencies with class member and function declarations, you can forward-declare a class:
class A;
class B {
A *a;
};
class A {
B *b;
};
To define class member functions that access members of the other class, you must define the function after the other class has been defined:
class B;
class A {
public:
void f(B &arg);
};
class B {
public:
void g(A &arg);
};
void A::f(B &arg) {
arg.g(*this);
}
void B::g(A &arg) {
arg.f(*this);
}
Usually, in a C++ project, you wouldn't even encounter this problem: You would put function definitions, i.e. implementations, into .cpp files, while putting the class definitions into header files. Class forward declarations, if neccesary, could be put into their own header files that are included by all headers that need them.
A full example of how you would split the above code into multiple files:
a.cpp
#include "a.h"
#include "b.h"
void A::f(B &arg) {
arg.g(*this);
}
b.cpp
#include "b.h"
#include "a.h"
void B::g(A &arg) {
arg.f(*this);
}
a.h
#ifndef _A_H_
#define _A_H_
#include "forward_declarations.h"
class A {
public:
void f(B &arg);
};
#endif //_A_H_
b.h
#ifndef _B_H_
#define _B_H_
#include "forward_declarations.h"
class B {
public:
void g(A &arg);
};
#endif //_B_H_
forward_declarations.h
#ifndef _FORWARD_DECLARATIONS_H_
#define _FORWARD_DECLARATIONS_H_
class A;
class B;
#endif //_FORWARD_DECLARATIONS_H_
As a general rule of thumb, if you need to forward-declare a class, you might have misdesigned something and should think about whether there is a better way (but there also are perfectly valid use cases that require class forward declarations).
If you don't understand my #ifndef, #define and #endif preprocessor lines: These are header guards, and should be used with all files that are included somewhere else, exception you know precisely what you're doing. Believe me. You'll regret ommiting one.
If your problem is cyclic dependancy, like this:
// DeviceManager.h
#include "device.h"
class DeviceManager
{
DeviceManager(Device& device) {}
};
// Device.h
#include "DeviceManager.h"
class Device
{
Device(DeviceManager& manager) {}
};
You can solve the problem be forward declaring one of the classes, and passing the object by pointer.
// Device.h
//#include "DeviceManager.h"
class DeviceManager;
class Device
{
Device(DeviceManager* manager) {}
};
Alright, I just thought give C++ a try (I currently do C#), now my first problem is class instantiating or calling a method in another class.
Here is my code:
My main Program entry:
#include <iostream>
#include "myClass.h"
using namespace std;
int main()
{
myClass* mc = new myClass();
}
The Class I'm trying to access:
#include "myClass.h"
myClass::myClass()
{
void DoSomething();
{
}
}
myClass::~myClass()
{
}
The Class Header:
#pragma once
class myClass
{
public:
myClass();
~myClass();
};
Now as you can see i have instantiated the class, but i cant access DoSomething() method.
This code simply declares a local function, and has an empty scope for fun:
myClass::myClass()
{
void DoSomething(); // local function declaration
{
// empty scope
}
}
If you want doSomething() to be a member of myclass, you have to declare it in the class definition:
class myClass
{
public:
myClass();
~myClass();
void doSomething();
};
then implement it
void myclass::doSomething() { .... }
Also note that you don't have to use new everywhere in C++. You can instantiate an object like this:
int main()
{
myClass mc;
}
Also note that using namespace std; isn't such a great idea anyway, at least not in real code.
this is a function declaration in a constructor (+an ampty scope within { }).
myClass::myClass()
{
void DoSomething();
{
}
}
You want a function declaration in class body (not in constructor) and definition of this function (this can be done immediately together with declaration or later as i.e. here):
class myClass
{
public:
myClass();
~myClass();
void doSomething();
};
implementation of constructor:
myClass::myClass() { .... }
implementation of your function, similarly:
void myClass::doSomething() { .... }
The method you are trying to use in main must be part of the class definition. You can write an inline function or can have a separate definition of that function. Also, you need to make that function public in order to access it from main.
UPDATE: Let me clarify my files and reiterate my question:
main.h
#include "other.h"
class MyClass
{
public:
void MyMethod();
void AnotherMethod();
OtherClass test;
}
main.cpp
#include "main.h"
void MyClass::MyMethod()
{
OtherClass otherTemp; // <--- instantitate OtherClass object
otherTemp.OtherMethod(); // <--- in this method here, is where I want to also call MyClass::AnotherMethod()
}
void MyClass::AnotherMethod()
{
// Some code
}
other.h
class OtherClass
{
public:
void OtherMethod();
}
other.cpp
#include "other.h"
void OtherClass::OtherMethod()
{
// !!!! This is where I want to access MyClass::AnotherMethod(). How do I do it?
// I can't just instantiate another MyClass object can I? Because if you look above in
// main.cpp, this method (OtherClass::OtherMethod()) was called from within
// MyClass::MyMethod() already.
}
So basically what I want is this: you instantiate object A, which in turn instantiates object B, which in turn calls a method that is from object A. I'm sure something like this is possible, but it might just be poor design on my part. Any direction would be greatly appreciated.
Some do one .h/.cpp per class:
my.h
#ifndef MY_H
#define MY_H
#include "other.h"
class MyClass
{
public:
void MyMethod();
OtherClass test;
}
#endif // MY_H
other.h
#ifndef OTHER_H
#define OTHER_H
class OtherClass
{
public:
void Othermethod();
}
#endif // OTHER_H
my.cpp
#include "my.h"
void MyClass::MyMethod() { }
other.cpp
#include "other.h"
#include "my.h"
void OtherClass::OtherMethod)()
{
// (ab)using MyClass...
}
If you're using only Visual Studio, you could use #pragma once instead of #ifndef xx_h #define xx_h #endif // xx_h.
EDIT: as the comment says, and also the related Wikipedia page, #pragma once is also supported (at least) by GCC.
UPDATE:
About the updated question, unrelated to #include, but more about passing objects around...
MyClass already has an embedded instance of OtherClass, test. So, in MyMethod, it's probably more like:
void MyClass::MyMethod()
{
test.OtherMethod();
}
And if OtherMethod needs to access the MyClass instance, pass this instance to OtherMethod either as a reference, or a pointer:
By reference
class OtherClass { public: void OtherMethod(MyClass &parent); }
void MyClass::MyMethod() { test.OtherMethod(*this); }
void OtherClass::OtherMethod(MyClass &parent)
{
parent.AnotherMethod();
}
By Pointer
class OtherClass { public: void OtherMethod(MyClass *parent); }
void MyClass::MyMethod() { test.OtherMethod(this); }
void OtherClass::OtherMethod(MyClass *parent)
{
if (parent == NULL) return; // or any other kind of assert
parent->AnotherMethod();
}
Define the function outside of either class in a C++ source file, not in the header:
void OtherClass :: Othermethod() {
// call whatever you like here
}
Create a .cpp file:
#include "main.h"
void OtherClass::Othermethod()
{
MyClass m; //ok :)
m.MyMethod(); //also ok.
}
Implementations don't belong in headers anyway.
Just #include it inside other.cpp