Alternative for forward declaration: two classes using each other - c++

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.

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.

c++ can i reuse class member's interface as interface, just like reuse base class's member

sometimes we need combine multiple class as a new class, see below:
class A
{
public:
void SomeHandle();
};
class B;
class C;
each of them provide some useful function,then i need a new class to provide a union of them, so i would write as below:
class Combine
{
public:
void Combine::SomeHandle();
private:
A objA;
B objB;
C objC;
};
but then i have to write lots of code to rediect call to Combine to corresponding object, like:
void Combine::SomeHandle()
{
objA.SomeHandle();
}
is there any simpler way expect macro to do that?
Are you looking for "Inheritance"?
class A
{
public:
void someHandle();
};
class B:public A
{...
};
allows you to write
B someB;
someB.someHandle();
class B "inherits" all interfaces from class A.
It's a very, very basic feature of OOP.

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.

Issue decoupling nested C++ classes

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)

C++ Encapsulation Techniques

I'm trying to properly encapsulate a class A, which should only be operated on by class B.
However, I want to inherit from class B.
Having A friend B doesn't work -- friendship isn't inherited.
What's the generally accepted way of accomplish what I want, or am I making a mistake?
To give you a bit more color, class A represents a complex system's state. It should only be modified by B, which are actions that can be applied to change class A's state.
It sounds like you may need to do a redesign; your class A represents a State, but your Class B represents a set of actions. There's a relationship there, but it's not an inheritance relationship. I'd suggest composition; you want more of a HASA relationship than an ISA relationship, as far as I can tell.
I assume you want to allow descendants of B to access A directly? If A and B are tightly coupled, you can make A a protected class definition within B itself, instead of being an independent definition. E.G.
class B
{
protected:
class A
{
};
};
Another idea is to create protected methods on B that delegate their actions to A. E.G.
class A
{
friend class B;
private:
void DoSomething();
};
class B
{
protected:
void DoSomething(A& a) { a.DoSomething(); }
};
If I understand you correctly, you want to have B and it's derivatives to have access to the internal implementation of class A, yes?
Unfortunately, C++ does not have the concept of "internal" protection levels that languages like C# and Java posses.
You can consider using the private implementation paradigm (pimpl) - also known as opaque pointers, to expose functionality within your system using public access levels, that consumers of A and B would not see.
Keeping everything as is, the easiest thing to do is to add protected methods to B that give access to the equivalent feature of A it would need. This opens the encapsulation to just subclasses of B.
The most straightforward way to do this is simply to have B contain an A:
class B {
protected:
A a_;
};
Then, you can write a class C which inherits from B and is able to manipulate A. If C shouldn't be able to do arbitrary things to the A, then make the A private in B and provide protected methods in B that C can use to do approved things to the A, like so:
class B {
private:
A a_;
protected:
void doSomethingToA();
};
Containment is the way to go (class B contains private member of type A) unless B needs to override some virtuals in A, in which case private inheritance is the closest thing.
I cant see why you would want to inherit. Make everything in A private and friend B. B then has a member of A which it can freely manipulate.
The way you describe this it sounds more like composition rather than inheritance. E.g.
class ComplexMachine {
public:
setState(int state);
};
class Operator {
public:
Operator(ComplexMachine & m) :_m(m) {};
void drive() { _m->setState(1); }
void turn() { _m->setState(2); }
void stop() { _m->setState(0); }
private:
ComplexMachine _m;
};
class SmoothOperator : public Operator { }
Working with the bits of information you have given:
Class B should be responsible for preserving the invariants of class A, and class B should be the only way to manipulate A. Any client - derived class or caller - should not need to know that A exists.
(From design POV, there's even no need for A to exist, but I have encountered enough practical reasons for such a separation that I won't hold it against you ;))
This might require a lot of boilerplate code to be written, or some trickery with the interface. e.g. if client should be allowed to use class A to query information but not to modify it, B could hand out a const & to the aggregated A. With a compiler supporting __declspec(property) or similar, the syntactic pain can be eased.
If you want to be sure that only B operates on A, make the instance of A private and expose a protected interface from B to its descendants.
class A
{
public:
void foo() {}
};
class B
{
private:
A a;
protected:
void CallAFoo() { a.foo() };
};
class C : public B
{
void goo() { CallAFoo(); }
};
From what I understand from your question, you will need some polymorphism. You need an abstract class A and class B inherits class A. Also, the protected keyword allows the classes that inherit to have access to certain information while at the same time deny access to anything else. Here is a little example:
// dynamic allocation and polymorphism
#include <iostream>
using namespace std;
class CPolygon {
protected:
int width, height;
public:
void set_values (int a, int b)
{ width=a; height=b; }
virtual int area (void) =0;
void printarea (void)
{ cout << this->area() << endl; }
};
class CRectangle: public CPolygon {
public:
int area (void)
{ return (width * height); }
};
class CTriangle: public CPolygon {
public:
int area (void)
{ return (width * height / 2); }
};
int main () {
CPolygon * ppoly1 = new CRectangle;
CPolygon * ppoly2 = new CTriangle;
ppoly1->set_values (4,5);
ppoly2->set_values (4,5);
ppoly1->printarea();
ppoly2->printarea();
delete ppoly1;
delete ppoly2;
return 0;
}
Code taken from cplusplus.com (contains information on polymorphism and abstract classes too).