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();
};
Related
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.
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.
I'm new to C++, and I'm familiar with Java. The first thing I was wondering about when I started looking at C++ code is that classes themselves (not the members) don't have access specifiers such private, protected and public. Exemples here and here.
public class A { // This line.
private class B { } // Not this line.
}
Why is that so?
There's no access modifier at the level of classes, since the language has no concept of package. But there is at the level of data members, member functions and inheritence:
class Foo {};
class Bar : public Foo {
public:
void bar() const {}
private:
int bar_(float) {}
int a, b, c;
};
The closest you can get is declaring nested classes inside a class:
class Foo {
struct Bar0 {
void bar0() const {}
};
struct Bar1 {
Bar0 b0;
Bar1() { b0.bar0();}
};
};
There's no need for class-level access specifier. If you want a private class, you can define it in an implementation file or an anonymous namespace. This sort of restriction is done at file-level for C++ (i.e. how you organize your headers, preprocessor directives).
Before edit:
They do, but they're not per-method. Also, classes have a default private specifier, so, unless otherwise noted, they are private.
class A
{
void foo(); //private
};
class B
{
void foo(); //private
public:
void foo1(); //public
void foo2(); //public
protected:
void foo3(); //protected
private:
void foo4(); //private
};
Note 1 C++ also has struct, which is identical to a class except the default access level is public.
Note 2 There is no package-scope in C++. In Java, protected gives access to the whole package, in C++ it just gives access to deriving classes.
Note 3 The friend keyword can be used to bypass restrictions, look it up.
C++ uses a slightly different syntax where access modifiers are specified for groups of declarations instead of individually:
class Test {
class MyPrivateClass {
// ...
};
void privateByDefault();
public:
void myPublicFunction();
void anotherPublicFunction();
private:
void myPrivateFunction();
public:
class MyPublicClass {
// ...
};
void morePublicFunctions();
protected:
// ...
};
Test::MyPrivateClass is inaccessible outside of Test, while Test::MyPublicClass can be used anywhere.
From your source: http://www.cplusplus.com/doc/tutorial/classes
private members of a class are accessible only from within other
members of the same class or from their friends. protected members are
accessible from members of their same class and from their friends,
but also from members of their derived classes. Finally, public
members are accessible from anywhere where the object is visible.
How can I reach privateMember without friend in all of the derived classes?
class parent{...}; //a virtual class
class A: public parent{...};
class B: public parent{...};
class C: public parent{...};
class D: public parent{...};
class E: public parent{...};
...
//each has a function, that want access to privateMember
class MyClass{
int privateMember;
friend parent;
//I know it doesnt't work, but this shows the best what I want
}
Leave it as is (with friend class parent) and add an accessor function to parent that A, B,... will use. It would be protected, so functions from outside the hierarchy can't use it.
class parent {
protected:
static int& getPrivate( MyClass & c ) { return c.privateMember; }
...
};
You have to do this, because friendship doesn't extend to derived classes.
You could create a getter function, that would return a privateMember:
int getPrivateMember() const { return privateMEmber; }
This must be a public method of course.
The simple answer here is to not go mucking with the internal state of other classes. Instead, use their public API. This way you never have to worry about locking yourself into an implementation AND you avoid a wide variety of potential problems with inadvertently breaking class invariants when you modify the variable.
How can classes in C++ be declared public, private, or protected?
In C++ there is no notion of an entire class having an access specifier the way that there is in Java or C#. If a piece of code has visibility of a class, it can reference the name of that class and manipulate it. That said, there are a few restrictions on this. Just because you can reference a class doesn't mean you can instantiate it, for example, since the constructor might be marked private. Similarly, if the class is a nested class declared in another class's private or protected section, then the class won't be accessible outside from that class and its friends.
By nesting one class inside another:
class A
{
public:
class B {};
protected:
class C {};
private:
class D {};
};
You can implement "private classes" by simply not publishing their interface to clients.
I know of no way to create "protected classes".
It depends if you mean members or inheritance. You can't have a 'private class', as such.
class Foo
{
public:
Foo() {} //public ctr
protected:
void Baz() //protected function
private:
void Bar() {} //private function
}
Or inheritance:
class Foo : public Bar
class Foo : protected Bar
class Foo : private Bar