In C++ you can't include Header Files in each other because of recursion. So you have to make use of Predefined Classes right? So I want to get the value of num in C.hpp and print it out in B.hpp.
C Class gets initialized before B Class which is expected.
Console Output
But when I'm trying to call A::instance->c it is NULL!
B Class with unitialized C Class
A.hpp
#include <iostream>
class C; // PREDEFINED CLASS
class B; // PREDEFINED CLASS
class A {
public:
inline static A* instance;
C* c{ 0 };
B* b{ 0 };
A() {
instance = this;
}
void start(B* b,C* c) {
this->c = c;
this->b = b;
}
};
B.hpp
#include "A.hpp"
#include "C.hpp"
class B {
public:
void call() {
if (A::instance->c)
std::cout << "C Num: " << A::instance->c->num << "\n";
else std::cout << "C Class is NULL!\n";
}
B() {
std::cout << "B init!\n";
call();
}
};
C.hpp
class C {
public:
int num = 0;
C() {
std::cout << "C init!\n";
num = 69;
}
};
Source.cpp
#include "A.hpp"
#include "B.hpp"
#include "C.hpp"
void main() {
A a;
a.start(new B(), new C());
}
C Class gets initialized before B Class which is expected.
No, it's not expected, the order of evaluation of function arguments is unspecified.
But even if that's the case as in your example output, you've created new C class object, and now you are trying to create B class object and during that, you are trying to access A::instance->c which is not set yet.
You set c for class A object in the start function, but you are still evaluating its parameters during this calls and didn't reach the actual body of the function.
Thus, the c in the class A is the default 0 as you set by C* c{ 0 };.
Related
I'm trying to write a program that calls for a function stored inside a class whose implementation is defined by another object instance.
Let me clarify this better: I would like to create an object A and call for its functions (like an abstract object), but the body of this functions should be defined by either an instance of class B or class C.
I know abstract classes exist in C++ and that i could just call the derived objects, but my goal is to call for object A methods without caring (or knowing in advance) whether an instance of object B or C was previously created.
I tried to use pointers to functions, unfortunately with no results. My code was something like this
Class A:
class A {
public:
static void (*someFunction)();
};
Class B:
class B {
public:
B(){
A::someFunction = someFunction;
}
private:
void someFunction(){
std::cout << "some function" << std::endl;
}
};
Main code:
B b;
A::someFunction();
What am I doing wrong or could be done in a more simple and elegant way? Sorry for the poor explaination and thank you in advance for your help.
Polymorphism exists for just this type of situation, eg:
class A {
public:
virtual ~A() = default;
virtual void someFunction() = 0;
};
class B : public A {
public:
void someFunction() override {
std::cout << "some function" << std::endl;
}
};
class C : public A /* or B*/ {
public:
void someFunction() override {
std::cout << "some other function" << std::endl;
}
};
void doIt(A &a) {
a.someFunction();
}
B b;
doIt(b);
C c;
doIt(c);
Online Demo
But, if that is not what you want, then consider having A use std::function instead of a raw function pointer. Then B and C can assign whatever they want to A::someFunction using lambdas or std::bind(), eg:
A.h:
#include <functional>
class A {
public:
static std::function<void()> someFunction;
};
A.cpp:
#include "A.h"
std::function<void()> A::someFunction;
B.h:
#include "A.h"
class B {
public:
B(){
A::someFunction = [this](){ someFunction(); };
or:
A::someFunction = std::bind(&B::someFunction, this);
}
private:
void someFunction(){
std::cout << "some function" << std::endl;
}
};
C.h:
#include "A.h"
class C {
public:
C(){
A::someFunction = [this](){ someFunction(); };
or:
A::someFunction = std::bind(&C::someFunction, this);
}
private:
void someFunction(){
std::cout << "some other function" << std::endl;
}
};
#include "A.h"
#include "B.h"
#include "C.h"
B b;
A::someFunction();
C c;
A::someFunction();
Online Demo
I have a little problem with this code :
#include <iostream>
class A {
public:
void PrintA() {
std::cout << "A";
}
};
class B : public A {
public:
void PrintB() {
std::cout << "B";
}
};
int main() {
A a;
a.PrintA();
B b;
b.PrintA();
b.PrintB();
system("PAUSE");
}
Can you tell me if there exist a way to define in A class an object B and use it's methods something like :
class A {
public:
void PrintA() {
std::cout << "A";
}
B bclass;
};
And use in main function something like :
int main() {
A a;
a.bclass->PrintB();
system("PAUSE");
}
The question you need to ask yourself
How does the compiler figure out the size of A
Well - It needs to figure out the size of B
But B has an A in it.
You can go around that loop forever
So you cannot do it.
So use a pointer and forward declaration
Generally functions definition is placed in cpp files and class definition in h or hpp files.
In cpp files you include both hpp with both classes.
Each function defined in cpp have see definition of both classes and may create new one of them.
But in declaration you may only use pointer or reference to object of that class.
== a.hpp ==
#pragma once
class B;
class A {
public:
void PrintA();
B* b;
};
== b.hpp ==
#pragma once
#include "a.hpp"
class B : public A {
public:
void PrintB();
A* a;
};
== a.cpp ==
#include "a.hpp"
#include "b.hpp"
void A::PrintA() {
b = new B();
std::cout << "A";
}
== b.cpp ==
#include "a.hpp"
#include "b.hpp"
void B::PrintB() {
a = new A();
std::cout << "A";
}
And main:
int main() {
A a;
a.PrintA();
a.b->PrintB();
B b;
b.PrintA();
b.PrintB();
system("PAUSE");
}
Worked example available at this link all in one file.
There one else link where seems Visual Studio compiler used.
Just for a sample, you can point to a B instance from an A instance like below, with a pointer:
class A {
public:
void PrintA() {
std::cout << "A";
}
std::unique_ptr<B> bclass;
};
A a;
A.bclass=new B;
A.bclass->PrintB();
The unique pointer will manage memory deallocation.
I am confused how to implement data member access from a different class.
I have three classes in three different header files.
A.h
#include "B.h"
#include "C.h"
class A{
B *b;
friend void dataaccess_b_from_class_A(int a);
}
B.h
class B{
}
C.h
class C{
void dataaccess_b_from_class_A(int a);
}
void C::dataaccess_b_from_class_A(int a)
{
b = new B(); //I got error as symbol b could not be resolved.
}
I like dataaccess_b_from_class_A() method from class C access data B *b from Class A.
I put friend function inside class A, but I got error as symbol b could not be resolved.How can I implement it?
EDIT1:
According to the discussion 'gmas80',
what I did was
class B; // forward declaration
class A{
public:
A(){};
private:
static B* b; // since in the dataaccess_to_class_A you are using new
friend class C; // this make b and dataaccess_from_class_C accessible
};
class B{
public:
B(){ cout << "B" << endl; };
// add content
};
class C{
public: // you need this keyword if you want to call this function from outside
void dataaccess_to_class_A(A a);
};
void C::dataaccess_to_class_A(A a)
{
A::b = new B(); //Error as undefined reference to class A::b
cout << "C" << endl; // test if called
}
If I don't include static, I got b could not be resolved.
If I include static, I got undefined reference.
Thanks
You have included so many mistakes in a so small piece of code! why don't you start simpler? Here a modified single-file version of your code that compiles:
#include <iostream>
using namespace std;
class B; // forward declaration
class A{
public:
A(){};
private:
B* b; // since in the dataaccess_to_class_A you are using new
void dataaccess_from_class_C(){ cout << "A" << endl; }; // test if called
friend class C; // this make b and dataaccess_from_class_C accessible
};
class B{
public:
B(){ cout << "B" << endl; };
// add content
};
class C{
public: // you need this keyword if you want to call this function from outside
void dataaccess_to_class_A(A a);
};
void C::dataaccess_to_class_A(A a)
{
a.b = new B(); // this is a potentially memory leak if you will not delete in somehow
a.dataaccess_from_class_C();
cout << "C" << endl; // test if called
}
// it is better if you post runnable code
int main() {
C c;
A a;
c.dataaccess_to_class_A(a);
}
AFTER EDIT1
Now you can start to move the class in a header file, but you need to add guardians to avoid multiple definitions..
a.h
#ifndef H_GUARDIAN_A
#define H_GUARDIAN_A
#include <iostream>
using namespace std;
class B; // forward declaration
class A
{
public:
A()
{};
private:
B* b; // since in the dataaccess_to_class_A you are using new
void dataaccess_from_class_C()
{
cout << "A" << endl;
}; // test if called
friend class C; // this make b and dataaccess_from_class_C accessible
};
class B
{
public:
B()
{
cout << "B" << endl;
};
// add content
};
class C
{
public: // you need this keyword if you want to call this function from outside
void dataaccess_to_class_A( A a );
};
void C::dataaccess_to_class_A( A a )
{
a.b = new B(); // this is a potentially memory leak if you will not delete in somehow
a.dataaccess_from_class_C();
cout << "C" << endl; // test if called
}
#endif
main.cpp
#include "a.h"
// it is better if you post runnable code
int main()
{
C c;
A a;
c.dataaccess_to_class_A( a );
}
Does it make sense for you? I simple moved the class declarations in another file that is included..
EDIT2
Now we split the class definitions in three different headers..
a.h
#ifndef H_GUARDIAN_A
#define H_GUARDIAN_A
#include <iostream>
using namespace std;
class B;
class A
{
public:
A(): b(NULL){}; // initialize to NULL the b pointer
~A(); // new entry: destructor to eventually delete b (only member function declaration)
private:
B* b; // since in the dataaccess_to_class_A you are using new
void dataaccess_from_class_C()
{
cout << "A" << endl; // test if called
};
friend class C; // this make b and dataaccess_from_class_C accessible
};
#endif
a.cpp // new entry! it avoids circular dependency.. the destructor is defined here
#include "a.h"
#include "b.h"
A::~A() // destructor that eventually clean memory for b
{
if( b ) delete b;
}
b.h
#ifndef H_GUARDIAN_B
#define H_GUARDIAN_B
#include "a.h"
class B
{
public:
B()
{
cout << "B" << endl;
};
// add content
};
#endif
c.h
#ifndef H_GUARDIAN_C
#define H_GUARDIAN_C
#include "b.h"
class C
{
public: // you need this keyword if you want to call this function from outside
void dataaccess_to_class_A( A a );
};
void C::dataaccess_to_class_A( A a )
{
a.b = new B(); // this is a potentially memory leak if you will not delete in somehow
a.dataaccess_from_class_C();
cout << "C" << endl; // test if called
}
#endif
main.cpp
#include "c.h"
// it is better if you post runnable code
int main()
{
C c;
A a;
c.dataaccess_to_class_A( a );
}
add
include "B.h"
in the beginning if the C.h
and define the type of b
B b( new B() );
also, specify the fully qualified method in your freind declaration:
friend void C::dataaccess_b_from_class_A(int a);
include C.h into A.h,
and do not forget include guards in each header
Another point. Why are you defining C::dataaccess_b_from_class_A in the header? I would suggest to do it in a separate file. Say, "C.cpp".
I have a class structure similar to the following
class A
{
public:
A(void);
~A(void);
void DoSomething(int i)
{
std::cout << "Hello A" << i << std::endl;
}
};
class B : public A
{
public:
B(void);
~B(void);
void DoSomething(int i)
{
std::cout << "Hello B" << i << std::endl;
}
};
class Ad : public A
{
public:
Ad(void);
~Ad(void);
};
class Bd : public B
{
public:
Bd(void);
~Bd(void);
};
I want to store instances of the derived classes in a container (standard map) as a collection of A*, then iterate through the container and call methods for each instance.
#include "A.h"
#include "B.h"
#include "Ad.h"
#include "Bd.h"
#include <map>
int main(int argc, char** argv)
{
std::map<int,A*> objectmap;
objectmap[1] = new Ad();
objectmap[2] = new Bd();
for (std::map<int,A*>::iterator itrobject = objectmap.begin();
itrobject!=objectmap.end(); itrobject++)
{
itrobject->second->DoSomething(1);
}
return 0;
}
The above code produces the following output.
Hello A1
Hello A1
Where I was expecting
Hello A1
Hello B1
because I was expecting DoSomething in B to hide DoSomething in A, and because I am storing A pointers, I would expect no object slicing (and looking at the object pointer in the debugger shows that the object has not been sliced).
I have tried down casting and dynamic casting the pointer to B, but it slices away the data members of Bd.
Is there any way to call B::DoSomething without casting the pointer to Bd? And if not, if I have many derived classes of B (e.g. Bda, Bdb, Bdc etc), is there some way to use RTTI to know which derived class to cast it to?
You need to make DoSomething() a virtual function in both classes to get the polymorphic behavior you're after:
virtual void DoSomething(int i) { ...
You don't need to implement virtual functions in every sub class, as shown in the following example:
#include <iostream>
class A {
public:
virtual void print_me(void) {
std::cout << "I'm A" << std::endl;
}
virtual ~A() {}
};
class B : public A {
public:
virtual void print_me(void) {
std::cout << "I'm B" << std::endl;
}
};
class C : public A {
};
int main() {
A a;
B b;
C c;
A* p = &a;
p->print_me();
p = &b;
p->print_me();
p = &c;
p->print_me();
return 0;
}
Output:
I'm A
I'm B
I'm A
Assume the following simple case (notice the location of virtual)
class A {
virtual void func();
};
class B : public A {
void func();
};
class C : public B {
void func();
};
Would the following call call B::func() or C::func()?
B* ptr_b = new C();
ptr_b->func();
Your code is invalid C++. What are the parentheses in class definition?
It depends on the dynamic type of the object that is pointed to by pointer_to_b_type.
If I understand what you really want to ask, then 'Yes'. This calls C::func:
C c;
B* p = &c;
p->func();
Examples using pointers as well as reference.
Using pointer
B *pB = new C();
pB->func(); //calls C::func()
A *pA = new C();
pA->func(); //calls C::func()
Using reference. Note the last call: the most important call.
C c;
B & b = c;
b.func(); //calls C::func()
//IMPORTANT - using reference!
A & a = b;
a.func(); //calls C::func(), not B::func()
Online Demo : http://ideone.com/fdpU7
It calls the function in the class that you're referring to. It works it's way up if it doesn't exist, however.
Try the following code:
#include <iostream>
using namespace std;
class A {
public:
virtual void func() { cout << "Hi from A!" << endl; }
};
class B : public A {
public:
void func() { cout << "Hi from B!" << endl; }
};
class C : public B {
public:
void func() { cout << "Hi from C!" << endl; }
};
int main() {
B* b_object = new C;
b_object->func();
return 0;
}
Hope this helps