Encapsulation in header files - c++

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.

Related

C++ Multilevel Inheritance, Polymorphism

Suppose i have three classes A, B and C. class B inherits from class A and the inheritance is private whereas class C inherits from B and the inheritance is public. Now class A has a protected function which class C wants to access. So, what must be done in class B to make that protected function available to class C.
Here is the link to the code : http://pastebin.com/9E2sLZzj
The "using" keyword makes a member of an inherited class visible, and resolvable, in the scope of its subclass. So, to make the privately-inherited member available to B's subclasses:
class A {
protected:
void foo() {}
};
class B : private A {
protected:
using A::foo;
};
class C : public B {
void bar()
{
foo();
}
};
Okay i got the solution
This code fragment worked after inserting it into Class B.
int get(){
return A::get();
}
Not sure what it does though

C++ allow derived classes of friend to have access to private nested class

Here's what I'm trying to do:
class A
{
friend class C (and all of C's derived classes)
public:
void DoAThing() { mpMyC->DelegateResponsibility(myB); }
private:
class B
{
};
B mMyB;
C* mpMyC;
};
class C
{
// No problem here- C can see B
virtual void DelegateResponsibility(const A::B& necessaryInfo);
};
class D: public C
{
// Uh-oh- we don't inherit friendship
virtual void DelegateResonsibility(const A::B& necessaryInfo);
};
In short, I have a private nested class inside A because it's an implementation detail of A. However, I'd like to delegate some responsibilities of A to C and C's derived classes to get some polymorphic behavior. I'd like to avoid having to add a friend class line every time someone derives from C. The standard workaround given for derived friend classes is "just add a protected accessor function to your base class and override it for derived members" but that only helps access private members of class A, not privately scoped classes. Is there any way to workaround this issue?
This should work:
class C
{
typedef A::B MyB;
virtual void DelegateResponsibility(const MyB& necessaryInfo);
};
class D: public C
{
// Uh-oh- we don't inherit friendship
virtual void DelegateResonsibility(const MyB& necessaryInfo);
};
You could put your class B in a detail namespace, at file scope.
something like this:
namespace my_hidden_area {
class B {
...
}
}
It's not as strong protection as making the class nested private, of course, but it should make it clear to outsiders that they should not be messing around with B.
If you're wondering why friendship is not inheritable, see this question: Why does C++ not allow inherited friendship?

Calling a protected method for a member object in C++

If i have two classes, for example like this
class A {
...
protected:
B* test;
aFunction();
};
class B {
...
protected:
A* test1;
public:
bFunction();
};
can I do this inside bFunction() of class B:
bFunction(){
test1->aFunction();
}
Basically, can I call a protected function of a certain class from the class that's not derived from that function?
The "point" of the protected is that only classes that are derived from the baseclass can call those functions.
If you have a good reason to do this, then make the class a friend, e.g. add friend class B; inside class A.
It is recommended to avoid such inevident mutual dependencies. A necessity to use friend functions often indicates bad architecture.
From cplusplus.com:
Private and protected members of a class cannot be accessed from
outside the same class in which they are declared. However, this rules
does not affect friends.
You can call protected and privat methods from other classes, when those are 'friends':
In your case that would be:
Class A {
...
protected:
B* test;
aFunction();
friend class B;
}
Often that is considered bad practice, but for tightly coupled classes that is ok.

Trouble with public/protected/private inheritance

I'm attempting a simple example of inheritance in C++. But I just can't get it down. When I try to get the protected members of class B inherited from class A it says that A::baz is protected.
#include <iostream>
class A {
public:
int foo;
int bar;
protected:
int baz;
int buzz;
private:
int privfoo;
int privbar;
};
class B : protected A {}; // protected members go to class B, right?
int main() {
B b;
b.baz; // here is the error [A::baz is protected]
}
I can't seem to find what I'm doing wrong. I've tried changing class B : protected A to : public A but it still doesn't work.
Protected inheritance just impacts how clients of your class see the public interface of the base class. Protected inheritance marks the public members of the base class as protected for users of your inherited class.
So baz in your example is not public, it is protected from B, hence the compiler error.
You can access protected members from inside a deriving class, not outside.
class B : protected A
{
void foo()
{
int x = foo; //ok
x = baz; //ok
x = privfoo; //error
}
};
Inheritance type only limits base class access. If, for example, you choose protected inheritance, all public methods in A will become protected to the outside, and the rest remain the same.
protected fields can only be accessed by methods in the class declaring them, or classes inheriting from the declaring class. you are trying to access a protected field ffrom a global function.
Because A::baz is protected, B can access it:
class B : public A
{
public:
int some_other_method()
{
return baz;
}
};
but that doesn't let other code access it.
The protected access specifier is similar to private. Its only
difference occurs in fact with inheritance. When a class inherits from
another one, the members of the derived class can access the protected
members inherited from the base class, but not its private members.
More on it here
You should read about public/private inheritance in C++. What you want to achieve is done by replacing
class B : protected A {};
by
class B : public A {};
EDIT: I read too fast and didn't notice you tried to access baz from main. You can only access it from a member method.
When a member is protected, it can only be accessed from within methods of the class that defines it and its descendants.
What you are trying to do is access the protected/private members from code external to these classes, which is not allowed. You can only access public members of a class from outside of class's scope.

Making classes public to other classes in C++

If I have two classes for example as follows:
class A {...}
class B {...}
If I want to make class A public to class B, do I just make the members of class A public or I can just use public class A {...}?
Is there a way to tell class B for example that only class A is public for you? In other words, can I make public classes to A protected or private to others? Or, this is just a matter of deriving a class (inheritance)?
Thanks.
There's a substantial difference between making the class public and making its contents public.
If you define your class in an include file (.h file) then you are making your class public. Every other source file that includes this include file will know about this class, and can e.g. have a pointer to it.
The only way to make a class private, it to put its definition in a source (.cpp) file.
Even when you make a class public, you don't necessarily have to make the contents of your class public. The following example is an extreme one:
class MyClass
{
private:
MyClass();
~MyClass();
void setValue(int i);
int getValue() const;
};
If this definition is put in an include file, every other source can refer to (have a pointer to) this class, but since all the methods in the class are private, no other source may construct it, destruct it, set its value or get its value.
You make the contents of a class public by putting methods from it in the 'public' part of the class definition, like this:
class MyClass
{
public:
MyClass();
~MyClass();
int getValue() const;
private:
void setValue(int i);
};
Now everybody may construct and destruct instances of this class, and may even get the value. Setting the value however, is not public, so nobody is able to set the value (except the class itself).
If you want to make the class public to only some other class of your application, but not to the complete application, you should declare that other class a friend, e.g.:
class SomeOtherClass;
class MyClass
{
friend SomeOtherClass;
public:
MyClass();
~MyClass();
int getValue() const;
private:
void setValue(int i);
};
Now, SomeOtherClass may access all the private methods from MyClass, so it may call setValue to set the value of MyClass. All the other classes are still limited to the public methods.
Unfortunately, there is no way in C++ to make only a part of your class public to a limited set of other classes. So, if you make another class a friend, it is able to access all private methods. Therefore, limit the number of friends.
You can use friendship.
class A { friend class B; private: int x; };
class B { B() { A a; a.x = 0; // legal };
If B has a strong interdependence to A, i suggest you use a nested class. Fortunately, nested class can be protected or private.
class A {
protected:
// the class A::B is visible from A and its
// inherited classes, but not to others, just
// like a protected member.
class B {
public:
int yay_another_public_member();
};
public:
int yay_a_public_member();
};