Inheritance c++ upcasting - c++

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.

Related

C++ Managing pointers to functions inside another class

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

C++ Class is not being Initialized

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 };.

C++ inheritance & virtual function problem

I want to show result is 2. (Now result is 1.)
How should I do? (I want to call B::test(). But Actually code cannot access b.h, b.c in main.c)
also I want to know that error from "public: virtual int test() {return 1;}" to "protected: virtual int test() {return 1;}" in a.h
the inheritance relationship are
super class A sub class B
super class A sub class C
but I can access A class in main.c
I want to result 2. ("a.test()" could not call "b.test()")
// a.h
#ifndef _A_
#define _A_
class A {
public:
A() {};
~A() {};
//protected:
virtual int test() {return 1;}
private:
friend class B;
};
#endif
// b.h
#ifndef _B_
#define _B_
#include "a.h"
class B : public A {
public:
B() {};
~B() {};
private:
int test() override;
friend class A;
};
#endif
// b.c
#include "b.h"
int B::test()
{
return 2;
}
// c.h
#ifndef _C_
#define _C_
#include "a.h"
class C : public A {
public:
C() {};
~C() {};
private:
int test() override;
friend class A;
};
#endif
// c.c
#include "c.h"
int C::test()
{
return 3;
}
// main.c
#include <iostream>
#include "a.h"
using namespace std;
int main(void)
{
A *a = new A();
cout << a->test() << "\n";
return 0;
}
Consider your code:
// main.c
#include <iostream>
#include "a.h"
using namespace std;
int main(void)
{
A *a = new A();
cout << a->test() << "\n";
return 0;
}
The key decider on behaviour is =new A().
If you change this to =new B() then you would get the result of '2' that you want.
However, you've had added the restriction 'code cannot access b.h'. This means that =new B() will not compile. Where does this restriction come from? You could achieve this with an extremely complicated factory pattern, but it seems unlikely this is what you are trying to do.
Access specifiers (private, protect, public) should be the same for the same method (test() in this case) at every level in the hierarchy. This is not absolutely enforced by the compiler, but is a clear best practice. There's very little difference her between making test() private or protected, but in both cases the expression:
a->test()
will fail in main, because it is outside of the class, and can only access public members.
Also worth pointing out that your friend declarations are entirely unnecessary in the code as shown.
Create object of type B, you still will be able to call test method, because A::test is public. This code will print 2:
int main(void)
{
A *a = new B();
// ^
cout << a->test() << "\n";
delete a; // (1)
return 0;
}
Also line (1) won't work properly unless you make A's destructor virtual (When to use virtual destructors?):
class A {
public:
A() {};
virtual ~A() {};
// ^^^^^^^
//protected:
virtual int test() {return 1;}
private:
friend class B;
};
UPD If for some reason you can't include b.h you can do the following:
a.h:
#ifndef _A_
#define _A_
class A {
...
};
A* CreateB();
#endif
a.c:
#include "a.h"
#include "b.h"
...
A* CreateB() {
return new B();
}
main.c:
#include <iostream>
#include "a.h"
using namespace std;
int main(void)
{
A *a = CreateB();
cout << a->test() << "\n";
delete a;
return 0;
}

In C++, Can't I implement this classes without separating header and cpp?

Suppose I have "A.hpp", "B.hpp", and "main.cpp".
A.hpp
#ifndef _A_HPP_
#define _A_HPP_
#include "B.hpp"
class A {
public:
B& b_;
A(B& b) : b_(b) {
}
void foo() {
b_.foo();
}
};
#endif
B.hpp
#ifndef _B_HPP_
#define _B_HPP_
#include "A.hpp"
class B {
public:
A* a_;
B() : {
a_ = new A( *this );
}
void foo() {
}
};
#endif
main.cpp
#include "B.hpp"
#include "A.hpp"
int main()
{
B b;
b.a->foo();
return 0;
}
I know why I can't compile main.cpp but don't know how can I fix this situation without seperating header file and source file for classes A and B. ( For example situation , classes A and B are using template )
Thanks in advance. :)
If I understand you correctly - you want to be able to compile main.cpp without needing separate translation units for A and B, and without having to seprate-out A and B's interface and implementation?
You can do this - but you will still need to follow the rules for forward-declaration:
class B; // class `B` forward-declaration
// define class A, but don't implement the parts that need B's definition
class A {
public:
B& b_; // `A` can use `B` here, but the compiler still doesn't know how B is defined
A(B&& b); // also need to define A's structure, but not the method implementations
void foo();
};
class B {
public:
A* a_;
B() : {
a_ = new A( *this );
}
void foo() { }
};
// now we can define `A` using the `A::` syntax, instead of class{}:
A::A(B&& b) : b_(b) { }
void A::foo() { b_.foo(); }
int main()
{
B b;
b.a->foo();
return 0;
}

Data access from a member function of different classes in C++

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".