What I found from all kinds of trial an error is that when you have components with circular dependency on each other (more so in C++ than in dynamic languages like python), you are asking for trouble, so I always make it a point of always defining a strict hierarchical relationship between classes.
In this case it seems that B is a higher level class than A, so let's keep it that way. How about something like this:
typedef interface struct; // in MSVC this is built into compiler
interface IOwnerOfA {
virtual int someFunctionCall() = 0;
}
class A {
IOwnerOfA* m_pOwner;
void DoSomething() { .... bunch of code; m_pOwner->someFunctionCall(); .... }
}
class B : private IOwnerOfA {
// yeah, cast is optional but I like them in these cases
B() : m_a( static_cast< IOwnerOfA* >( this ) {}
virtual int someFunctionCall() {
... provide specific functionality A needs;
and nothing else;
}
A m_a;
}
So now the hierarchy is IOwnerOfA <-- A <--- B. Everyone knows about the interface, B knows of A, A knows nothing about B, so tomorrow you could have C using A without having to make any changes in A.
As far as your question about storing a member variable vs. pass in as parameter into DoSomething(), that's really up to you. If it is only one isolated place, I'd probably pass into a parameter. If the relationship between classes really is that B is an "owner" of A and in A needs to call back into B (via IOwnerOfA interface) in a number of places, then store as a member.
Another alternative for you to consider (if you are doing a one off in one place) is instead of using interfaces and class pointers, you can take a functional approach and have DoSomething() accept std::function as a parameter type. Then use std::bind() to pass in a bound member function. Might sound a bit crazy, but it's actually somewhat straightforward (except for the compiler errors if you get something wrong) and very flexible (once you get past the compiler errors)
To add to what @JTrana, commented on. There are definitely cases where B owns A and for whatever reason A needs to callback into B. If you need to do this, the only two options I see are using interface (yes one extra level of indirection) and using direct types (circular dependency). Between those 2 choices, extra complexity of the interface is a winner for me. However, these true cases are few and far between. Most of the time you might be able to refactor your app so you don't need to do this circular loop.
Consider if part of B that A needs could be switched out into a smaller C class:
class C { // contains some commonly used functionality
}
class A {
DoSomething( C* pCommonGuy) { .... }
}
class B {
A m_a;
C m_c;
}