Details the declaration of nested classes and their functions in C++ programming

  • 2020-05-07 20:13:35
  • OfStack

You can declare another class within the scope of one class. Such classes are called "nested classes." Nested classes are considered within the scope of a closed class and can be used within that scope. To reference a nested class from a scope outside its immediate enclosing scope, you must use a fully qualified name.
The following example shows how to declare nested classes:


// nested_class_declarations.cpp
class BufferedIO
{
public:
  enum IOError { None, Access, General };

  // Declare nested class BufferedInput.
  class BufferedInput
  {
  public:
   int read();
   int good()
   {
     return _inputerror == None;
   }
  private:
    IOError _inputerror;
  };

  // Declare nested class BufferedOutput.
  class BufferedOutput
  {
   // Member list
  };
};

int main()
{
}

Declare BufferedIO::BufferedOutput and BufferedIO in BufferedIO::BufferedInput. These class names are not visible outside the scope of class BufferedIO. However, objects of type BufferedIO do not contain any objects of type BufferedInput or BufferedOutput.
Nested classes can only use names, type names, static member names, and enumerators directly from closed classes. To use the names of other class members, you must use Pointers, references, or object names.
In the previous BufferedIO example, the enumeration IOError can be accessed directly by a member function in a nested class, BufferedIO::BufferedInput, or BufferedIO::BufferedOutput, as shown in the function good.
note
nested classes declare types only within the scope of the class. They do not cause the creation of containing objects for nested classes. The previous example declares two nested classes, but does not declare any objects of these class types.
When a type name is declared with a forward declaration 1, an exception to the scope visibility of the nested class declaration is thrown. In this case, the class name declared by the forward declaration is visible outside the closed class and its scope is defined as the smallest closed non-class scope. Such as:


// nested_class_declarations_2.cpp
class C
{
public:
  typedef class U u_t; // class U visible outside class C scope
  typedef class V {} v_t; // class V not visible outside class C
};

int main()
{
  // okay, forward declaration used above so file scope is used
  U* pu;

  // error, type name only exists in class C scope
  u_t* pu2; // C2065

  // error, class defined above so class C scope
  V* pv; // C2065

  // okay, fully qualified name
  C::V* pv2;
}

Access in nested classes
embeds one class into another without giving special access to the member functions of the embedded class. Similarly, a member function of a closed class does not have special access to a member of a nested class.
Member functions in the nested class
The member functions that
declares in nested classes can be defined in the file scope. The previous example may have been written:


// member_functions_in_nested_classes.cpp
class BufferedIO
{
public:
  enum IOError { None, Access, General };
  class BufferedInput
  {
  public:
    int read(); // Declare but do not define member
    int good(); // functions read and good.
  private:
    IOError _inputerror;
  };

  class BufferedOutput
  {
    // Member list.
  };
};
// Define member functions read and good in
// file scope.
int BufferedIO::BufferedInput::read()
{
  return(1);
}

int BufferedIO::BufferedInput::good()
{
  return _inputerror == None;
}
int main()
{
}

In the previous example, the qualified-type-name syntax was used to declare function names. Statement:


BufferedIO::BufferedInput::read()

Represents "the BufferedIO function as a member of the read class (within the scope of the BufferedInput class)." Since this declaration USES the qualified-type-name syntax, it is possible to construct the following form:


typedef BufferedIO::BufferedInput BIO_INPUT;

int BIO_INPUT::read()

The above declaration is equivalent to the previous one, but it USES the typedef name instead of the class name.
The friend function in the nested class
Friend functions declared in
nested classes are considered to be within the scope of nested classes rather than closed classes. Therefore, friend functions do not gain specific access to members of a closed class or to member functions. If you need to use the name declared in the nested class in the friend function, and the friend function is defined in the file scope, use the qualified type name, as shown below:


// friend_functions_and_nested_classes.cpp

#include <string.h>

enum
{
  sizeOfMessage = 255
};

char *rgszMessage[sizeOfMessage];

class BufferedIO
{
public:
  class BufferedInput
  {
  public:
    friend int GetExtendedErrorStatus();
    static char *message;
    static int messageSize;
    int iMsgNo;
  };
};

char *BufferedIO::BufferedInput::message;
int BufferedIO::BufferedInput::messageSize;

int GetExtendedErrorStatus()
{
  int iMsgNo = 1; // assign arbitrary value as message number

  strcpy_s( BufferedIO::BufferedInput::message,
       BufferedIO::BufferedInput::messageSize,
       rgszMessage[iMsgNo] );

  return iMsgNo;
}

int main()
{
}

The following code demonstrates the function GetExtendedErrorStatus declared as a friend function. Copies the message from a static array to a class member in a function defined within the file scope. Note that a better implementation of GetExtendedErrorStatus would declare it as:


int GetExtendedErrorStatus( char *message )

Using the previous interface, many classes can use the service of this function by passing the memory location of the error message to be copied.


Related articles: