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.
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.
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.
I have class C and it is inheriting from Class A and Class B.
Is it possible for class A to access Class B function( eg fun1() ) using this inheritance. A and B are both independent class and fun1() is only in class B.
Not strictly through inheritance. Although A and B are parents of C, A and B have no relationship and no way to access eachother.
It is possible through inheritance and polimorphism, then class A have a virtual method that C implements calling the function in B, like this:
class A {
public:
b get_b() { return do_get_b(); }
private:
virtual do_get_b() = 0;
};
class B {
public:
b some_b;
};
class C : public A, public B {
private:
virtual do_get_b() {return some_b;}
}
You could check with dynamic_cast to see if your object of A is really a object of C, and thereby of B
void A::foo()
{
B* pB = dynamic_cast<B*>(this);
if (pB) pB->bar();
}
But if A and B are really independent of one another it is probably better to find a different solution.
Sometimes, it is possible. An example how to achieve this.
That example applies to a diamond hierarchy, which is a bit more complicated than yours. In your terms, ClassA and ClassB should be derived from class Base, ClassC is derived from ClassA and ClassB.
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).