13

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.

Simplicity
  • 47,404
  • 98
  • 256
  • 385

3 Answers3

24

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.

Patrick
  • 23,217
  • 12
  • 67
  • 130
  • When you write: `int getValue() const;`, does `const` here mean: return the value as a constant? Thanks. – Simplicity Jan 25 '11 at 19:19
  • 1
    The const means that the method will not change the instance itself, so getValue will not change the instance of MyClass on which you call getValue. In general, a const return value (as in "const int getValue();") doesn't make sense. What does make sense is if you return a pointer, that the pointer points to a const value (like in "const char *getName()"). – Patrick Jan 25 '11 at 20:24
3

You can use friendship.

class A { friend class B; private: int x; };
class B { B() { A a; a.x = 0; // legal };
Puppy
  • 144,682
  • 38
  • 256
  • 465
  • @DeadMG. Is this another form for friendship: "class B: public A"? Thanks. – Simplicity Jan 25 '11 at 10:58
  • @user588855, no, that is [inheritance](http://www.cplusplus.com/doc/tutorial/inheritance/). – Péter Török Jan 25 '11 at 11:00
  • @DeadMG. So, how can we do a public class? Is it correct by using the keyword "public" before the class name? – Simplicity Jan 25 '11 at 11:00
  • @user588855, in C++ there is no accessibility restrictions for classes (such as in e.g. Java or C#), only for class members. So `public class X { ... };` is not valid C++. A class is visible to another class if you `#import` its header file. – Péter Török Jan 25 '11 at 11:02
  • As DeadMG told you. No, writing public before the class keyword is not C++. – Daniel Gehriger Jan 25 '11 at 11:02
  • @Péter Török. When you say: "A class is visible to another class if you #import its header file", what is "visible" here? I mean will it be "public" or "protected"? Or, this depends on the accessor specifiers of the class members only? Thanks. – Simplicity Jan 25 '11 at 11:08
  • @user588855, in Java terms, all C++ classes are public by default, and you have no way of changing that. – Péter Török Jan 25 '11 at 11:10
  • Just as a little aside, if you simply want to make everything public you can make it a struct instead of a class. One of the very few differences between a class and a struct is the default access specifier for members. But yes, if you want to make the members accessible to only a specific class, then you need friendship. – wich Jan 25 '11 at 11:11
  • @Péter Török. Got what you mean, thanks a lot and thanks to you all for your answers. – Simplicity Jan 25 '11 at 11:11
  • @Péter Török, when user588855 says public class I think he/she refers to the accessibility of the members of the class. – wich Jan 25 '11 at 11:12
  • @wich. So, can "structs" than contain functions? Thanks. – Simplicity Jan 25 '11 at 11:12
  • @user588855 yes, structs can contain member functions as well, even virtual ones, constructors, operator overloaders and the whole shebang. – wich Jan 25 '11 at 11:16
  • @user588855, @wich, technically yes, however, the common C++ convention is to use structs only as dumb data classes, i.e. no logic. If you need logic associated with your data, you almost always want encapsulation too, thus you should declare it a `class` (where the default access is `private`). – Péter Török Jan 25 '11 at 11:42
  • @Péter Török #import is not part of C++ standard. – UmmaGumma Jan 25 '11 at 11:53
3

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();
};
BatchyX
  • 4,986
  • 2
  • 18
  • 17