Issue decoupling nested C++ classes - c++

I am having a simple C++ problem but I am not sure how to solve this.
I have two classes, A and B which are not inherited in anyway. A is Client class, and B is a class that stores a list of Client (A class).
I want only B to instantiate and destroy the class B, but I want other parts of my code to be able to call methods within class A.
Initially I had the following:
class B {
public:
class A {
public:
void setX(int val);
int getX();
private:
int x;
A();
~A();
};
B()
~B()
....
};
This allows me to call A's constructor/destructor from B, and makes A's constructor/destructor private from the rest, but calling setX() and getX() on A became troublesome as I have to call B::A.
I thought putting A in it's own file (it's own class, not nested), as other classes can call methods on A. But now B cannot access A's constructor/destructor as it is private. If I make it public, then anyone can create an object of class A.
I am not sure what's the best way to do this. If A is it's own class, how can I keep the constructor/destructor available only to B please, while other classes can call setX() and getX() on an object from A please?

Declaring A in its own, non-nested class but with a friend class of B should do the trick.
Friend classes
Leaving you with:
class B{
public:
B()
~B()
....
};
and
class A {
friend class B;
public:
void setX(int val);
int getX();
private:
int x;
A();
~A();
};

I think you might messed up.(Or I did when reading your example! :P)
Declaring a nested class makes the nested class able to access all member of the nesting class and not the inverse as I understood from your explanation.
I mean: B within A means that A access al member of B, not the inverse!
Nested Classes Question(Check second response, not first!)
If when saying in your question "I want only B to instantiate and destroy the class B" you mean "I want only B to instantiate and destroy the class A" then you have two options.
You can either make B nested class of A, letting B access al private stuff of A
or use friend classes.(Check #Egg response)

Related

C++ How to Refer to a Class' Members' Members Without Accessing Original Member

Hi I know the title is a little hard to understand, and that's just because I have no idea how to phrase this problem. Fortunately, I can provide an easy-to-understand example of my problem. Imagine a base class A derived class B and unrelated class C setup as follows:
class A
{
public:
};
class B : public A
{
public:
C c;
};
class C
{
public:
void foo();
};
I want to know how to call foo() using an object of class B without doing this:
B b;
b.c.foo();
but rather this:
B b;
b.foo();
Additionally, I don't want to inherit from class C or make copies of class C's functions. Is this possible with a simple implementation? Thanks!
Your constraints mean your example does not make sense unless the function foo is static; if it is not then you need to provide information about the instance of C you are using before foo makes sense; so mentioning c would be essential. If it is static then C::foo works but not b.foo(). If you want a member function for B that calls b.c.foo() then you should write one as suggested above.
Perhaps you meant to privately inherit C in B:
class B : private C , public A
{
public:
using C::foo;
};
will do the trick.

Encapsulation in header files

I have a header file with 2 classes. class A (which is a very big class) and class B that inherits class A. I don't want people to be allowed to create objects of class A or even be able to see its static members. They should only to work with class B. What is the best way of doing that.
(Generally speaking A is a "helper class")
To restrict the creation of the class, make the constructor of class A private and declare class B as a friend class. This way only B can instantiate A.
class B;
class A
{
private:
A();
friend class B;
};
The same applies to methods (static or not): make them all private and the friend statement will allow B to access A's members.
Edit: works with protected as well.
I don't want people to be allowed to create objects of class A
What you are looking for is called an "abstract base class". In C++, any class that has at least one abstract member is automatically an abstract class, there is no additional keyword like in other languages.
class A
{
public:
virtual void Test() = 0; // abstract, has no implementation
};
class B : public A
{
public:
virtual void Test() {} // not abstract, has an implementation
};
int main()
{
A a; // this will produce a compiler error.
B b; // this is fine
return 0;
}
or even be able to see its static members
Well, don't make them public. Either make them protected or private and grant friend access to your B class.

Alternative for forward declaration: two classes using each other

I have class A which has to implement some functions. Since implementing one of them needs it's own data structures, I assumed A contain another class B, which has all needed data structures and functions. However, B is also need to use data structures and functions of A, as well. I used two classes calling each others using forward declaration. But there is still problems. For example, I need to make all data structures in A public, in order to B can access it. I tried using friend classes, but when I declare B as an abstract classes with sub-classes which implements B's functionalities, I need to make all data structures of A, as public. Because friend class doesn't work for inherited sub-classes, all data structures of A, needs to be public. This makes my design quite messy.
class B;
class A{
protected:
int ds[100];
B * b;
public:
a_func(){
b->b_func();
}
};
class A;
class B{
A * a;
public:
b_func(){
a->a_func();
}
};
class sub_B:public B{
public:
b_func(){
a->a_func();
a->ds ...;
}
}
My question is: is there any alternative design?
I also tried making A an abstract class and class B implements a function of it, however, it doesn't conceptually makes sense to build an object of B, when I want an object of A.
You don't have to provide member function definitions inside a class definition:
class A;
class B;
class A {
// no need for public
B * b;
void a_funct(void);
};
class B {
// no need for public here, too
A * a;
void b_funct(void);
};
// the following goes in a source file,
// otherwise you should mark it as inline
void A::a_funct() {
b->b_funct();
}
void B::b_funct() {
a->a_funct();
}
Note that above code serves only as example, in its current shape it's nothing but a fancy endless (recursion) loop.

Protected member is not accessible through a pointer or object [duplicate]

Can someone explain why this code doesn't work.
class A
{
public:
A(void){}
virtual ~A(void){}
protected:
A* parent;
};
class B : public A
{
public:
B(void){parent = new B;}
~B(void){delete parent;}
protected:
int a;
};
class C : public B
{
public:
C(void){}
virtual ~C(void){}
void f(void){ ((B*)parent)->a; }
};
How is it possible that C isn't able to access members of B?
If I convert parent to a C* in stead of a B* it works fine. But I don't want users to take any unnecessary risks. Is there a cleaner way access a?
Thanks.
From an object of the C class, you can access protected members of B, but only if they're part of some object of class C (maybe yours, maybe not). In other words, to access a from C, you need a pointer (or a reference) to C. This is what the protected modifier means.
The reason for this is the following. The ((B*)parent) pointer may point to some other subclass of B, completely different from C, and that subclass may have the a member inaccessible.

Inheritance without containing?

I have class A. And I have class B. And I have many-many classes derived from class B.
I want to achieve this: derivatives of B should have access to the protected variables of A. Whithout each of them containing an instance of A, which would need a lot of memory.
So I guess public inheritance is not a good idea this time. How do I solve this?
Thanks!
You could do it with friend and accessor functions. This does trust B to stay off A's privates - don't see a good way to let only B and subclasses access only protected members of A unless there's an inheritance relationship between A and B.
class A {
friend class B;
protected:
int X;
};
class B {
protected:
static int getX(A const & a) { return a.X; }
};
class C : public B {
public:
void foo(A const & a) { int bar = getX(a); }
};
Make the classes that are derived from B friends of A.
From what I understand children of B are unrelated to class A and as such should not have access to non-public parts of A.
The right way to get access to A's data within B child classes is through A's public interface. If such public interface isn't adequate then that's a signal that either you're trying to do something that's a poor design, or that A's public interface needs to be improved.