Smart pointers with optional ownership - c++

I'm trying to allow a class to contain a pointer, which may either be an owned pointer or a borrowed pointer. In the former case, it should destroy the owned object itself; in the latter case, it shouldn't destroy the pointed-to object.
In code, I have classes A, B and C. I'm aiming for the following (simplified) definitions, where B is the class that needs to own a pointer:
class C {
...
};
class B {
C *c;
B(C *c) : c(c) {
}
};
class A {
C c1;
B b1, b2;
// b2 leaks pointer to C
A() : b1(&c1), b2(new C()) {
}
};
When an instance of A destructs, it destroys c1, b1 and b2. Ideally, the destruction of b2 should delete the anonymous C instance, but the destruction of b1 should not delete anything (since c1 will be destroyed by A directly).
What kind of smart pointer can I use to achieve this? Or, is the best solution just to pass an ownership flag to B?

If you are sure and can guarantee that the reused C will not be destroyed early (triple check that), there are multiple ways to go about it.
Some you might consider:
You can manually manage the pointer and a flag. Make sure you get the copy-semantic right, e.g. like this:
class B {
std::unique_ptr<C> c;
bool shared = false;
B(C& c) : c(&c), shared(true) {}
B(C *c = 0) : c(c) {}
~B() { if (shared) c.release(); }
};
You could use a custom deleter, like this:
template <class T> struct maybe_delete
{
void operator()(T* p) const noexcept {if(!shared) delete p;}
bool shared = false;
};
template <class T> struct maybe_delete<T[]>
{
void operator()(T* p) const noexcept {if(!shared) delete [] p;}
template <class U> void operator()(U*) const = delete;
bool shared = false;
};
class B {
std::unique_ptr<C, maybe_delete> c;
B(C& c) : B(&c) {this->c.get_deleter().shared = true;}
B(C *c) : c(c) {}
};
You could take a peek at std::shared_ptr, though that is probably severe overkill and might have too much overhead for you.

While I fear for the potential abuse that B is open to, you could do this:
class B {
C *c;
bool owned;
B(C& c) : c(&c), owned(false) {}
B(C *c) : c(c), owned(true) {}
~B() { if (owned) delete c; }
};
class A {
C c1;
B b1, b2;
A() : b1(c1), b2(new C()) {}
};

There is no way to archive this behavior without side effects, as far as I know. If it is just usual pointers (not COM), than you can access C via shared_ptr in both classes. If only B owns C, than they both will be destroyed with B's destroy. If both A & B owns C, than C will be destoyed only when last remaining alive owner (be it A or B) will be destroyed.
I know such practice to think about ownership:
If method gets just a normal pointer, than it is meant that pointer will be used only inside that method. So, B will be:
class B1 {
B(C *c) {
//do some staff with c
}
void doSomeStaff(C*) {}
};
Or using & (cleaner, if your framework accept it):
class B2 {
B(C& c) {
//do some staff with c
}
void doSomeStaff(C&) {}
};
If method gets a shared pointer, it need this pointer for future reuse (keep it):
class B3 {
public:
std::shared_ptr<C> c;
B(std::shared_ptr<C> c) : c(c) {
}
};
So, now you can call b1.doSomeStaff(b3.c) or b2.doSomeStaff(*b3.c) without thinking who must destroy the pointed object C. You know only, that this object will be used in b1. That's all.
Do not forget to specify that you need shared_ptr, not C* in method - shared_ptr is an object, which increments reference count to object when copied. And not increments, but creates a new shared_ptr with reference count = 1, when constructed from C*.
This is not the answer to your question, but some of the common uses. See unique_ptr in Deduplicator's in answer. Also check: http://www.boost.org/doc/libs/1_55_0/libs/smart_ptr/smart_ptr.htm. Even if you don't use boost, there is a good theory for using different approaches to hold objects. Also check this answer: What is a smart pointer and when should I use one?

Pass in a unique_ptr via std::move for the owned version and pass in a reference for the unowned version:
no runtime overhead outside a unique_ptr
avoids incorrect usage
avoids having to mess around with custom destructors
no ambiguity
Minimal working example:
#include <iostream>
#include <memory>
class C
{
public:
~C() { std::cout << "Goodbye\n"; }
void SayHello() { std::cout << "Hello\n"; }
};
class B
{
std::unique_ptr<C> owned;
C* unowned;
public:
B(C& c) : owned(nullptr)
, unowned(&c)
{ }
B(std::unique_ptr<C> c) : owned(std::move(c))
, unowned(owned.get())
{ }
C& GetC() { return *unowned; }
};
int main()
{
C stackC;
std::unique_ptr<C> heapC(new C);
B b1(stackC);
B b2(std::move(heapC));
b1.GetC().SayHello();
b2.GetC().SayHello();
}
OUTPUT:
Hello
Hello
Goodbye
Goodbye

Related

Avoid null pointers while accessing objects in a tree hierarchy of classes

I have to work with a tree based hierarchy of objects where I need to access the deepest element that contains the data required by the application. I'm not sure if the previous statement explains in its best the problem itself so its better to present it with an example. Given the following scenario:
class A {
private:
B* _b;
public:
B* getB() {return _b;}
};
class B {
private:
C* _c;
public:
C* getC() {return _c;}
};
class C {
private:
int _n;
public:
int getN() {return _n;}
};
The desired operation would be to access n via A. So I would call the following:
A foo;
foo.getB()->getC()->getN();
The problem comes when any of the parts of the path are null we end up having a core dump. In the above scenario if B is null we end up in a core dump scenario.
Therefore I seek help and advice on any strategy or pattern that I can use to avoid this core dumps scenarios. If the path is extremely big I end up checking every single pointer if its valid and end up having really ugly code and also risk that I might have missed checking a part of the path. Note: I do not have access to change the implementation of the hierarchy of classes (A,B,C) as they are generated code and I do not have access to change the generator. Changing the previous would be my preferred solution but unfortunately I cannot.
In order to avoid having null pointers, you may want to establish a class-invariant that the member is never null. This can be achieved with following steps:
Encapsulate access to the member so that nothing outside the class can set the member. You've already achieved this through the use of private access. Just make sure that you pass/return a reference or a pointer to the member from a member function to the outside.
Ensure that no member nor friend function ever sets the member to null.
Also ensure that the member is always initialised. This is achieved by use of a custom constructor. Example:
class A {
B* b;
public:
A(B* b) : b(b) {
if (!b) {
// unlike indirection through null pointer, an exception can
// be caught and (potentially) handled gracefully at runtime
throw std::runtime_error("Naughty!");
}
}
// following prevents passing null literal at compile time
A(std::nullptr_t) = delete; // nullptr
A(int) = delete; // 0
// since it is never null, we can safely return a reference
B& getB() {return *b;}
}
While references have the nice property of not being ever null, they are tricky as members, since they are also not assignable. As an argument to a constructor, they are tricky since it is generally not conventional or expected for a class object to keep references to objects passed into a constructor. As such, I advocate the use of pointers in this case even when null is undesirable.
Note: I do not have access to change the implementation of the hierarchy of classes (A,B,C) as they are generated code and I do not have access to change the generator.
In this case you may instead wrap the generated classes with better classes:
class AWrapper {
A a;
// custom implementation that encapsulates A
}
If null pointers are valid values that cannot be avoided, then such invariant is of course not possible. In such case, you must always check whether the pointer is null before indirecting through it:
if (B* b = foo.getB())
if (C* c = b->getC())
c->getN();
Another thing that you might consider is whether all these pointers are necessary. Perhaps it would be simpler if the classes contained each other instead of indirectly referring to one another.
You need to test all along the way:
A foo;
B* BPrt = foo.getB();
if (BPrt)
{
C* CPtr = BPrt->getC();
if (CPtr)
{
int n = CPtr->getN();
...
Here's how I solved the problem:
#include <iostream>
using namespace std;
class C {
private:
int _n;
public:
int getN() {return _n;}
};
class B {
private:
C* _c;
public:
C* getC() {return _c;}
};
class A {
private:
B* _b;
public:
B* getB() {return _b;}
};
int main(void);
int main() {
static B b;
static C c;
static A foo;
unsigned int n;
B *bPtr; C *cPtr;
/* --RECODE (CHAIN-CALL): foo.getB()->getC()->getN();-- */
bPtr = (B *) (foo.getB());
cPtr = (C *) (bPtr ? bPtr->getC() : 0);
n = (int) (cPtr ? cPtr->getN() : 0);
/* --USE (CAST) and (TERNARY) instead of (CHAIN-CALL)-- */
cout << n << endl;
return n;
}
If the classes cannot be changed then the checking could be done via a template:
template <typename T, typename A, typename ...Args>
auto recurse(T t, A a, Args... args)
{
if (!t)
throw std::exception{};
auto next = (t->*a)();
if constexpr (sizeof...(Args) > 0)
return recurse(next, args...);
else
return next;
}
Then call as follows:
recurse(&foo, &A::getB, &B::getC, &C::getN);
The problem is not with a pointer being null. That is in-fact good as it mostly crashes at runtime. What if it's not null but has been previously freed/deleted ? The usage will probably lead to Undefined Behaviour.
A better way would be to use references if you can:
class A
{
private:
B& _b;
public:
A(B& b): _b{b} {}
B& getB ()
{
return _b;
}
};
Or something like that. Then you at-least don't have anything dangling (unless you are also using pointers somewhere).
If you have to use pointers then use one of the smart-pointers - see if std::unique_ptr solves if for you. If not then for shared ownership use std::shared_ptr and so on. Also ensure the way you initialise objects don't lead to a default null there.
You can make sure that your pointers are always initialized, if possible:
class C {
private:
int _n = 0;
public:
int getN() {return _n;}
};
class B {
private:
static C default_c;
C* _c = &default_c;
public:
C& getC() {return *_c;}
};
C B::default_c; // An out-of-line static member definition is required.
class A {
private:
static B default_b;
B* _b = &default_b;
public:
B& getB() {return *_b;}
};
B A::default_b; // An out-of-line static member definition is required.
int main() {
A a;
std::cout << a.getB().getC().getN() << '\n';
}
Note that pointers make better members than references because the references break value semantics and make your class non-assignable.
Did you consider:
try {
foo.getB()->getC()->getN();
}
catch(...)
{
//Here you know something is Null
}
That seems the simplest safest,when dealing with existing code.

Are smart pointers capable of removing other references to its object from containers?

I would like to implement this:
Object A owns an Object B (has a pointer to it)
When Object A is destroyed, Object B is destroyed too.
Object C has a std::vector of pointers to Object B-s.
When Object B is destroyed, remove its pointer from Object C's vector.
Is this possible with the combination of different smart pointers?
Let's think in terms of roles (and for now ignore threads):
Object A owns the lifetime of B
Object C is an observer of B's lifetime
You do not say whether there is a relationship between A and C so I will assume that A is aware of the involvement of C at the point of its constructor (let's use C as a configurable factory).
There are 2 places that B's lifetime events can create observations - the constructor / destructor of B (bad - tight coupling) or an intermediate factory (better - loose coupling).
So:
#include <memory>
#include <algorithm>
struct B {
};
struct C {
std::shared_ptr<B> make_b() {
auto p = std::shared_ptr<B>(new B(), [this](B *p) {
this->remove_observer(p);
delete p;
});
add_observer(p.get());
return p;
}
private:
void add_observer(B *p) {
observers_.push_back(p);
}
void remove_observer(B *p) {
observers_.erase(std::remove(std::begin(observers_), std::end(observers_), p),
std::end(observers_));
}
std::vector<B *> observers_;
};
struct A {
A(C &factory)
: b_(factory.make_b()) {}
std::shared_ptr<B> b_;
};
int main() {
// note: factory must outlive a1 and a2
C factory;
A a1(factory);
A a2(factory);
}
Note that while I have used a shared_ptr I could just have easily used a unique_ptr in this case. However I would then have coupled A with the deleter type in the pointer - so I'd either had to create my own type-erased deleter type or coupled A to C more tightly (which I wanted to avoid).
Object A owns an Object B (has a pointer to it)
When Object A is destroyed, Object B is destroyed too.
Object C has a std::vector of pointers to Object B-s.
When Object B is destroyed, remove its pointer from Object C's vector.
Object A can have its lifetime managed by shared_ptr.
It has full control over the lifetime of B:
struct A {
std::unique_ptr<B> b;
};
or
struct A {
B b;
};
We'll add an observe_B method:
struct A {
std::unique_ptr<B> b;
B* observe_B() { return b.get(); }
B const* observe_B() const { return b.get(); }
};
which we'll make logically const. For the case where we have an actual B, we just do & instead of .get(). So we don't care how B is allocated (pointer or in the body of A) anymore.
Now we have a relatively complex lifetime requests. Judicious use of shared_ptr may be appropriate here. In fact, shared_from_this:
struct A:std::enable_shared_from_this<A> {
std::unique_ptr<B> b;
B* observe_B() { return b.get(); }
B const* observe_B() const { return b.get(); }
std::shared_ptr<B const> get_shared_B() const {
return {shared_from_this(), observe_B()};
}
std::shared_ptr<B> get_shared_B() {
return {shared_from_this(), observe_B()};
}
};
Here we use the "aliasing constructor" of shared pointer to return a shared pointer to a non-shared object. It is intended for exactly this purpose. We use the shared lifetime semantics of A, but apply it to a B*.
In C we simply store a vector<weak_ptr>.
struct C {
std::vector<std::weak_ptr<B>> m_Bs;
};
Now, when an A goes away, the weak_ptr to the "contained" B loses its last strong reference. When you .lock() it, it now fails.
struct C {
std::vector<std::weak_ptr<B>> m_Bs;
void tidy_Bs() {
auto it = std::remove_if( begin(m_Bs), end(m_Bs), [](auto&& x)->bool{return !x.lock();});
m_Bs.erase(it, end(m_Bs));
}
};
tidy_Bs removes all of the "dangling" weak_ptrs to B in m_Bs.
To iterate, I'd typically do this:
struct C {
std::vector<std::weak_ptr<B>> m_Bs;
void tidy_Bs() {
auto it = std::remove_if( begin(m_Bs), end(m_Bs), [](auto&& x)->bool{return !x.lock();});
m_Bs.erase(it, end(m_Bs));
}
template<class F>
void foreach_B(F&& f) {
tidy_Bs();
auto tmp = m_Bs;
for (auto ptr:m_Bs)
if (auto locked = ptr.lock())
f(*locked);
}
};
which passes the f a B& for each of the still existing Bs in the m_Bs vector. While it is in there, it cleans up the dead ones.
I copy the vector because while iterating, someone could go and change the contents of m_Bs, and to be robust I cannot be iterating over m_Bs while that is happening.
This entire technique can be done without A being managed by shared_ptr; but then B has to be managed by shared_ptr.
Note that an operation that would "normally" cause A to be destroyed may not actually do it if C currently has a .lock() on the B contained within A. Practically there is no way to avoid that, other than making C crash.

How to distinguish objects of derived classes C++

Look at following code:
class A
{
protected:
int aa = 1;
};
class B : public A
{
private:
int bb = 2;
public:
int getbb() { return bb; }
};
class C : public A
{
private:
int cc = 3;
public:
int getcc() { return cc; }
};
int main()
{
std::vector<A> a;
B b;
C c;
a.push_back(b);
a.push_back(c);
a[0].getbb(); //getbb() unaccessible;
a[1].getcc(); //getcc() unaccessible;
}
A is the based class. B and C is the derived classes. I want to set a vector to hold either B or C, and use vector a to hold A. However, since a is a vector containing A's objects, I can't access methods in B and C. Is there anyway to make a[0].getbb() and a[1].getcc() work?
Your vector of A is not capable of holding Bs or Cs, because it stores A by value, resulting in object slicing when B or C is stored. In particular, this means that when you store B, only aa gets stored; bb gets sliced away.
In order to store subclasses without slicing use a container of pointers - preferably, of smart pointers.
This wouldn't help you access functionality specific to B or C without a cast. One way to solve this problem is to give virtual member functions for B's and C's functionality to A, and make calls through A-typed reference of B or C.
Not without invoking undefined behaviour.
The problem is that a.push_back(b) and a.push_back(c) do not append objects b and c to the vector. They create instances of A that hold only the "A parts". This is called object slicing.
So there is no object of type B and no object of type C in the vector.
You force the issue and make your code compile by doing something like
static_cast<B &>(a[0]).getbb();
but this just has undefined behaviour, since it treats a[0] as being of type B when it is really of type A. Which makes it a really bad idea. Although it will (probably) compile, it could do anything - and probably not what you expect.
If your vector contains A * rather than A it is possible. For example;
int main()
{
std::vector<A *> a;
a.push_back(new B);
a.push_back(new C);
B* b = dynamic_cast<B *>(a[0]);
if (b) // if a[0] actually points at a B ....
b->getbb();
else
complain_bitterly();
C *c = dynamic_cast<C *>(a[1]);
if (c)
c->getcc();
else
complain_bitterly();
}
Of course, doing this has practical trap doors as well - such as requiring class A having at least one virtual member. It would be better off to work with a polymorphic base, and override virtual functions.
In other words, your design is broken, so fix it so it doesn't somehow require you to morph an object to a different type.
An alternative to using pointers is to use a vector of std::reference_wrappers and polymorphic classes. Small example below:
#include <functional> // for std::reference_wrapper
#include <iostream>
#include <vector>
class A
{
public:
virtual void printme()
{
std::cout << "A" << std::endl;
}
virtual ~A() = default;
};
class B: public A
{
public:
void printme() override
{
std::cout << "B" << std::endl;
}
};
class C: public A
{
public:
void printme() override
{
std::cout << "C" << std::endl;
}
};
int main()
{
std::vector<std::reference_wrapper<A>> a;
B b;
C c;
a.emplace_back(b);
a.emplace_back(c);
a[0].get().printme(); // need to "get()" the raw reference
a[1].get().printme();
}
Live on Coliru
According the the cpp reference, there seems to be a way to achieve this by using dynamic_cast. You first need to make your vector a vector of pointers to the base class A. Then when accessing any element, you can check if it is a B* (or a C*) by checking the result of the dynamic_cast operator.
From the CPP reference:
dynamic_cast < new_type > ( expression )
... If the cast is successful, dynamic_cast returns a value of type new_type. If the cast fails and new_type is a pointer type, it returns a null pointer of that type...
Accordingly, you can do this:
std::vector<A*> a;
B b;
C c;
a.push_back(&b);
a.push_back(&c);
...
int i = something;
B* pB = dynamic_cast<B*>(a[i]); if(pB != nullptr) pb->getbb();
C* pC = dynamic_cast<C*>(a[i]); if(pC != nullptr) pC->getcc();
p.s: It is highly questionable as design approach though. The recommended OOP approach would be certainly to use a virtual method in the base class A and override it in B and C. But (hopefully) this answers the exact question as stated in the title.
If you're sure they're instances of B and C, use cast:
static_cast<B>(a[0]).getbb();
static_cast<C>(a[1]).getcc();
OK, you may also create a vector of A*:
std::vector<A*> as;
as.push_back(new B);
as.push_back(new C);
B* b = (B*) as[0];
b->getbb();
c->getcc();
Now you only have to remember about freeing objects with delete.
You may use "Type IDs":
class A {
// ...
virtual int getTypeID() { return 0; }
}
class B {
// ...
virtual int getTypeID() { return 1; }
}
// analogically for C
It's virtual but is in prototype of A
Now use:
switch(a.getTypeID()) {
case 0:
// It's normal A
break;
case 1:
// It's B
// ...
break;
case 2:
// It's C
// ...
break;
}

c++ : pointer to a class instance created in constructor

First, sorry for thw poor title... I don't really know how to express with one
sentance what I mean... You are weclome to edit the title.
I have three classes A, B and C.
class A{
public:
A(double a):a_(a){}
private:
double a_;
}
class B{
public
B():a_ptr_(NULL){}
B(A const& a):a_ptr_(new A(a)){}
~B(){ delete a_ptr_; }
void set(A const& a){ a_ptr_ = new A(a); }
private:
A* a_ptr_;
}
class C{
public
C():a_ptr_(NULL){}
C(A const& a):a_ptr_(&a){}
void set(A const& a){ a_ptr_ = &a; }
private:
A* a_ptr_;
}
My problem is that if I do
B b(A(1.0));
C c(A(1.0));
the class A is instanciated twice for B (two creation constructor calls).
C::a_ptr_ is problematic. If I do :
B b;
C C;
{
A a(1.0);
b.set(a);
c.set(a);
}
I have the same problems outside the brackets.
I would like to find a way to store a pointer on A in B or C without
copying the class A too many times and without having undefined pointers.
I've found something with a move constructor but I've never used such.
Any idea ? Thx !
std::shared_ptr is exactly what you need. This class is used for storing one pointer in different places. The target object will be deleted after the last shared_ptr pointing to it is destroyed. Since you are clearing the memory in the destructor, your classes obtain ownership of the A object. You can use something like this:
class B{
public
B():a_ptr_(NULL){}
B(A * a): a_ptr_(a){ }
~B(){}//don't need to do anything here.
void set(A * a){ a_ptr_.reset(a); }
private:
std::shared_ptr<A> a_ptr_;
}
<...>
class C should be written in a similar manner
<...>
A * a = new a(1.0);
B b(a);
C c(a)
Now, if you want to make a constructor or set method that takes a by reference, you will not be able to avoid copying it. Also, in this case you can't safely take the address of this variable.

C++ pointers to class instances

I have an (for C++ programmers better than me) simple problem with classes and pointers.
I thought about posting example code describing my problem but I found it easier to just explain it in words.
Assuming I have three classes:
Class A: The main class - it contains an instance of both B and C.
Class B: This class contains a method that outputs some string, call it Greet().
Class C: This one has a method too, but that method has to call Greet() in the instance of B that is located in class A. Let's name it DoSomethingWithB()
So the program starts, in the main function I create an instance of A. A, again, creates instances of B and C. Then, A calls C.DoSomethingWithB();.
And there my problem begins: I can't access B from inside C.
Obviously, I will need to pass a pointer to B to the DoSomethingWithB() function so that I can call B.Greet() from inside C
Long explanation, short question: How do I do this?
Example code incoming:
#include <iostream>
using namespace std;
class B
{
public:
void Greet( )
{
cout<<"Hello Pointer!"<<endl;
}
};
class C
{
public:
void DoSomethingWithB( )
{
// ... b.Greet( ); Won't work obviously
}
};
class A
{
public:
B b; // Not caring about visibility or bad class/variable names here
C c;
void StartTest( )
{
c.DoSomethingWithB( );
}
};
int main( )
{
A mainInstance;
mainInstance.StartTest();
}
Wouldn't you simply pass a pointer or reference to he B object?
class C
{
public:
void DoSomethingWithB( B& b)
{
b.Greet( ); // will work fine
}
};
class A
{
public:
B b; // Not caring about visibility or bad class/variable names here
C c;
void StartTest( )
{
c.DoSomethingWithB( b);
}
};
If the DoSomethingWithB() function won't modify the passed in B instance, you should mark the reference const so it can be called with a const B object (for example if the owning A object happens to be const):
void DoSomethingWithB( B const& b);
You have a few options for how to pass the B object to the function:
as a reference (void DoSomethingWithB( B& b)) which will let the function modify the passed in object. Changes will be refelected in the object that's passed in.
as a const reference (void DoSomethingWithB( B const& b)) which won't let the function modify the passed in object (unless the constness is cast away - something which can lead to undefined behavior if done on an object the is truely const)
as a pointer or const pointer to a B object (void DoSomethingWithB( B* b) or void DoSomethingWithB( B const* pb) ). These have similar performance to passing by reference, but the function could be passed a NULL pointer which needs to be dealt with properly (by not dereferencing it in that case). Also, the call of the function would need to change slightly to pass the address of the B object:
c.DoSomethingWithB( &b);
as a pass-by-value parameter (void DoSomethingWithB( B b)). This has difference that the function can do whatever it likes with theo bject passed in and it won't affect the originally passed object since the function is dealing with a copy. The disadvantage is that passing the parameter causes a copy to be made which might be expensive. You could also pass in a const value, but there's little to recommend that over passing a const reference.
Note that when chosing the parameter passing method, you should first chose based on the sematics of what you need the function to do (or not do). Worry about efficiency later. Always first design and code for correctness - worry about efficiency only after you have the design and code correct.
Change the functions to the following:
void DoSomethingWithB(B& b)
{
b.Greet();
}
... and in A ...
c.DoSomethingWithB(b);
You can do it just as you said -- pass a pointer (or a reference) to B in to DoSomethingWithB():
class C
{
public:
void DoSomethingWithB(B & bInstance)
{
bInstance.Greet( ); // should work fine!
}
};
Then you'll invoke it like so:
class A
{
public:
B b; // Not caring about visibility or bad class/variable names here
C c;
void StartTest( )
{
c.DoSomethingWithB( b );
}
};
I'd suggest using the reference approach here rather than a pointer, since:
Your object is an automatic class member, and
Passing a null B object into the function is not meaningful in this case.
In class C, declare the method DoSomethingWithB() like this:
void DoSomethingWithB( B* b )
{
b->Greet();
}
And in class A call it like this:
void StartTest()
{
c.DoSomethingWithB( &b );
}
Since you mentioned pointers, I answered using pointers. In C++ however, you should try to use const references whenever you can. That would of course require a small change to the existing code:
void DoSomethingWithB( const B& b )
{
b.Greet();
}
// and
void StartTest()
{
c.DoSomethingWithB( b );
}
I can't access B from inside C
Instead of having C call methods in B, why not have C return information to the caller so it can do the operation?
When I hit these I've found it's because I've got my classes organized poorly. Usually if I rethink them the difficulty disappears with a new organization.
class C
{
public:
C (B & b) : b(b) {}
void DoSomethingWithB( )
{
// ... b.Greet( ); Use b;
}
private:
B & b;
};
class A
{
public:
B b; // Declare b before c!
C c;
A() : c (b) {}
void StartTest( )
{
c.DoSomethingWithB( );
}
};