3

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");
}
zVoxty
  • 39
  • 6
  • 1
    No, A can't contain a B object, because B is derived from A, but it can contain a pointer to one. –  Jan 14 '17 at 17:40
  • Can you give me an example please, i try to find on google some but nothing clear... How to make this pointer? – zVoxty Jan 14 '17 at 17:42
  • You will find plenty of examples of using pointers here: http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – Sam Varshavchik Jan 14 '17 at 17:43
  • You asked `I have a problem with this code` and then you show the code. Then you give a scenario of an option or method of what you would like to try and then show how you would like to use it in your main. What I see missing is the actual problem with the original code? You never clearly state what the problem is nor do you show any output of what your program does and an output as a reference of what it's intended should be. So from that I think that this question is inconclusive or too vague. – Francis Cugler Jan 14 '17 at 18:22

3 Answers3

3

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

Ed Heal
  • 59,252
  • 17
  • 87
  • 127
  • I try to make something like B * bclass = new B but it's saying undefined type b. PS: I use forward declaration now – zVoxty Jan 14 '17 at 17:46
  • @zVoxty That is most likely because B hasn't been defined yet when A is being defined. As Ed Heal wrote, you need forward declarations to indicate that B exists and will be defined later. – synchronizer Jan 14 '17 at 17:48
  • What you just say is concerning inheritance. There is not possible `class A : public B {}` with `class B : public A{}`. But seems author is not require such closed graph of recursion. – oklas Jan 14 '17 at 17:53
  • Either B is a member of A or B inherits A - So B needs to include A's data either way. As to the view on the outside world that is a different question – Ed Heal Jan 14 '17 at 17:56
  • @zVoxty: A forward declaration alone does not solve this problem. A forward declaration is just a promise to the compiler that the full class definition will be available as soon as it's actually needed. For `new B`, it is needed already for a number of reasons. For example, the compiler cannot even know whether `B` actually has an accessible constructor until it has seen `B`'s definition. You should take a step back and read more material on the topic. You shouldn't have any problems finding a working example for a forward declaration to give you an idea of how this is done in C++. – Christian Hackl Jan 14 '17 at 18:12
  • @ChristianHackl Untill now I didn't find an working example :-? – zVoxty Jan 14 '17 at 18:20
  • There link at the end of my answer to worked one. Please copy carefully. – oklas Jan 14 '17 at 18:24
  • 1
    @zVoxty: Then I wonder how and where you searched, because when I enter "forward declaration c++" at Google, then the very first result already takes me to a Stack Overflow page with a perfect working example in an answer with 195 upvotes. – Christian Hackl Jan 14 '17 at 18:24
0

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.

oklas
  • 7,935
  • 2
  • 26
  • 42
  • This has nothing to do with the OP's question. –  Jan 14 '17 at 17:49
  • Why? OP ask how to `a.bclass->PrintB()` and my example show it `a.b->PrintB()`. Clarify please. – oklas Jan 14 '17 at 17:58
  • Go to link that I just published press `compile` and `run`. See results. And than go to your development environment and check code again please. – oklas Jan 14 '17 at 18:12
  • @oklas Because you edited it substantially after my comment. –  Jan 14 '17 at 18:14
  • I try on that link and work but in visual studio 15\ its said unitialized local variable 'a' used – zVoxty Jan 14 '17 at 18:16
  • Yes, this is naturally touching `the real time`. – oklas Jan 14 '17 at 18:16
  • I dont understand :-? – zVoxty Jan 14 '17 at 18:19
  • Your code is not identical of demonstarated code. That error (or warning) message may appear if you use variable before initialize. But my code have no such instructions. – oklas Jan 14 '17 at 18:22
  • @oklas I just copy paste it from site to VS15 – zVoxty Jan 14 '17 at 18:24
  • I add link to another site where seems visual studio compiler is used. – oklas Jan 14 '17 at 18:34
  • @oklas I find the problem if I delete a.PrintA(); it said 'unitialized varialbe a' ok but how to just use A a; a.b->PrintB(); ?? When I declare the pointer B* b; and i try to alloc memory : B* b = new B in class A, i get 'use of undefined type of B' So how to solve this ... – zVoxty Jan 14 '17 at 18:39
  • See carefully sequences of code strings. Sequences mean much. Your modifications of code broke sequences. – oklas Jan 14 '17 at 18:43
  • @oklas Yes it broke when i delete a.PrintA() but i dont need that i just need to print B instead of AB – zVoxty Jan 14 '17 at 18:44
  • It is becouse object `b` initialized in `PrintA()`. If you do not call it object is not initialised and program crashed. Make now your logic concerning initialisation of `b`. – oklas Jan 14 '17 at 18:50
  • Do not forget to make answer as answered and vote please. I am happy to help. – oklas Jan 14 '17 at 18:50
  • Of course i will vote, but why to initalize in `PrintA()` can i initialize it in class A? – zVoxty Jan 14 '17 at 18:55
  • Use initialization method [like this](http://www.tutorialspoint.com/compile_cpp_online.php?PID=0Bw_CjBb95KQMbkFrRDc1Y1hOWkE) Be careful with initialization in costructor. If you want to initialize in constructor you need special variable to protect indefinite loop. – oklas Jan 14 '17 at 19:10
  • @oklas it works now but where can i talk with you in private my base solution didn't work well... – zVoxty Jan 14 '17 at 19:42
-1

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.

Guillaume Racicot
  • 39,621
  • 9
  • 77
  • 141
Jeandey Boris
  • 743
  • 4
  • 9