0

In the below example I want to be able to access vector cList in class B in the function ShareData. How do I do that?

I have written a sample code. It fails to compile (Error message: B has no constructors). Even if it did, does the line cObj = new B(*this); introduce any circular dependency?

#include "stdafx.h"
#include <vector>

class B;

class A
{
public:
    B* cObj;
    std::vector<B*> cList;
    A()
    {
        cObj = new B(*this);
    }
};

class B
{
public:
    B(A& aObj) : aObjLocal(aObj) {};
    void ShareData(int result)
    {
        for (auto& iterator : aObjLocal.cList)
        {
            (*iterator).ShareData(result);
        }
    }
private:
    A& aObjLocal;
};


void main()
{
    A aMain;
    B bMain(aMain);
    bMain.ShareData(10);
}

Thanks in advance for sharing the knowledge.

Engineero
  • 12,340
  • 5
  • 53
  • 75
JayHawk
  • 275
  • 1
  • 5
  • 15

3 Answers3

2

When you are using forward declarations, you need to make sure that any usage of the forward-declared type which needs full type happens after the type becomes fully defined.

In your case, it means that your code should like following:

class B;

class A
{
public:
    B* cObj;
    std::vector<B*> cList;
    A();
};

class B {
   ...
};

inline A::A()
{
    cObj = new B(*this);
}

Also, while doing so, you certainly would want to get rid of owning B*, and instead use std::unique_ptr there.

SergeyA
  • 61,605
  • 5
  • 78
  • 137
1

cObj = new B(*this);
You cann use B here since it's not yet defined. Put this under the definition of B:

A::A()
{
    cObj = new B(*this);
}

and remove the inline definition.

1

The line

    cObj = new B(*this);

does not work in A's constructor since the definition of B is not visible at that line. Move the implementation of A's constructor after B has been defined.

class A { ... };

class B { ... };

inline A::A()
{
    cObj = new B(*this);
}
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • Doing so results in error: "'A::A': cannot define a compiler-generated special member function (must be declared in the class first)" – JayHawk Aug 09 '18 at 19:31
  • @JayHawk, you have to declare the constructor in the class. `A();`. You just can't define it. – R Sahu Aug 09 '18 at 19:40
  • Great! Thank you. – JayHawk Aug 09 '18 at 20:03
  • Is there any risk if the header file and the implementation of the methods, including the constructors are in separate files? – JayHawk Aug 09 '18 at 20:12
  • @JayHawk, are you talking about "separate .h files" or "separatre .h files and .cpp files"? – R Sahu Aug 09 '18 at 20:14
  • I am talking about the case where class A and class B, including their members is declared in one header file and the implementation of their methods are in another cpp file. Does ir matter where the constructor A:A() is present (header or cpp file)? Thanks! – JayHawk Aug 09 '18 at 20:33
  • @JayHawk, IMO, it is preferable to put the implementation of the constructor in a .cpp file. Just make sure to remove the `inline` qualifier. – R Sahu Aug 09 '18 at 20:36
  • Thanks! So there is no risk of circular dependency? – JayHawk Aug 10 '18 at 00:38
  • @JayHawk, circular dependency is easily avoided by understanding when forward declaration is enough and when it is not. Use of a .cpp file to implement the member functions is certainly helpful. You might find a related post interesting: [When can I use a forward declaration?](https://stackoverflow.com/questions/553682/when-can-i-use-a-forward-declaration) – R Sahu Aug 10 '18 at 05:08