Home

Class Nesting

 

Introduction

A class can be created inside of another class. A class created inside of another is referred to as nested:

Nesting a Class

To nest a class, simply create it as you would any other. Here is an example of a class called Inside that is nested in a class called Outside:

value class Outside
{
	value class Inside
	{
	};
};

In the same way, you can nest as many classes as you wish in another class and you can nest as many classes inside of other nested classes if you judge it necessary. Just as you would manage any other class so can you exercise control on a nested class. For example, you can declare all necessary variables or methods in the nested class or in the nesting class. When you create one class inside of another, there is no special programmatic relationship between both classes:  just because a class is nested doesn't mean that the nested class has immediate access to the members of the nesting class. They are two different classes and they can be used separately. 

The name of a nested class is not "visible" outside of the nesting class. To access a nested class outside of the nesting class, you must qualify the name of the nested class anywhere you want to use it. This is done using the :: operator. For example, if you want to declare an Inside variable somewhere in the program but outside of Outside, you must qualify its name. Here is an example:

using namespace System;

value class COutside
{
public:
	void ShowOutside()
	{
		Console::WriteLine(L"=-= Outside =-=");
	}

	value class CInside
	{
	public:
		void ShowInside()
		{
			Console::WriteLine(L"-=- Inside -=-");
		}
	};
};

int main()
{
    COutside ^ out = gcnew COutside;
    COutside::CInside ^ ins = gcnew COutside::CInside;

    out->ShowOutside();
    ins->ShowInside();

    Console::WriteLine();
    return 0;
}

This would produce:

=-= Outside =-=
-=- Inside -=-

Press any key to continue . . .

Because there is no programmatically privileged relationship between a nested class and its "container" class, if you want to access the nested class in the nesting class, you can use its static members. In other words, if you want, you can declare static all members of the nested class that you want to access in the nesting class. Here is an example:

using namespace System;

value class COutside
{
public:
	void ShowOutside()
	{
		Console::WriteLine(L" =-= Outside =-=");
		CInside::FromInside();
	}

	value class CInside
	{
	public:
		static String ^ InMessage;

		void ShowInside()
		{
			Console::WriteLine(L" -=- Inside -=-");
		}

		static void FromInside()
		{
			CInside::InMessage = L"This is inside";
			Console::WriteLine(CInside::InMessage);
		}
	};
};

int main()
{
    COutside ^ out = gcnew COutside;
    COutside::CInside ^ ins = gcnew COutside::CInside;

    out->ShowOutside();
    ins->ShowInside();

    Console::WriteLine();
    return 0;
}

This would produce:

=-= Outside =-=
This is inside
-=- Inside -=-

Press any key to continue . . .

In the same way, if you want to access the nesting class in the nested class, you can go through the static members of the nesting class. To do this, you can declare static all members of the nesting class that you want to access in the nested class. Here is an example:

using namespace System;

value class COutside
{
public:
	void ShowOutside()
	{
		Console::WriteLine(L"=-= Outside =-=");
		CInside::FromInside();
	}

	static void FromOutside()
	{
		OutMessage = L"This is Outside";
		Console::WriteLine(OutMessage);
	}

	static String ^ OutMessage;

	value class CInside
	{
	public:
		static String ^ InMessage;

		void ShowInside()
		{
			Console::WriteLine(L"-=- Inside -=-");
		}

		static void FromInside()
		{
			CInside::InMessage = L"This is inside";
			Console::WriteLine(CInside::InMessage);
		}

		void ShowOutside()
		{
			COutside::FromOutside();
		}
	};
};

int main()
{
    COutside ^ out = gcnew COutside;
    COutside::CInside ^ ins = gcnew COutside::CInside;

    out->ShowOutside();
    ins->ShowInside();
    out->FromOutside();

    Console::WriteLine();
    return 0;
}

This would produce:

=-= Outside =-=
This is inside
-=- Inside -=-
This is Outside

Press any key to continue . . .

Instead of static members, if you want to access members of a nested class in the nesting class, you can first declare a variable of the nested class in the nesting class. In the same way, if you want to access members of a nesting class in the nested class, you can first declare a variable of the nesting class in the nested class.

Implementing Methods of a Nested Class

In the previous lesson, we saw that C++ allows you to define a method outside of the class by qualifying its name. Here is an example:

value class COutside
{
public:
	void ShowOutside();
};

void COutside::ShowOutside()
{
	Console::WriteLine(L"=-= Outside =-=");
}

To define a method of a nested class outside of the nesting class, you must qualify its name from the parent class. To do this, type the name of the nesting class, followed by ::, followed by the name of the nested class, followed by ::, and followed by the name of the method of the nested class. Here is an example:

using namespace System;

value class COutside
{
public:
	void ShowOutside();

	static void FromOutside()
	{
		Console::WriteLine(L"This is Outside");
	}

	value class CInside
	{
	public:
		void ShowInside();

		static void FromInside()
		{
			Console::WriteLine(L"This is inside");
		}

		void ShowOutside()
		{
			COutside::FromOutside();
		}
	};
};

void COutside::ShowOutside()
{
	Console::WriteLine(L"=-= Outside =-=");
}

void COutside::CInside::ShowInside()
{
	Console::WriteLine(L"-=- Inside -=-");
}

int main()
{
    COutside ^ out = gcnew COutside;
    COutside::CInside ^ ins = gcnew COutside::CInside;

    out->ShowOutside();
    out->FromOutside();
    ins->ShowInside();
    ins->FromInside();

    Console::WriteLine();
    return 0;
}

When implementing a static method globally, remember that you must omit the static keyword:

using namespace System;

value class COutside
{
public:
	void ShowOutside();
	static void FromOutside();

	value class CInside
	{
	public:
		void ShowInside();
		static void FromInside();
	};
};

void COutside::ShowOutside()
{
	Console::WriteLine(L"=-= Outside =-=");
}

void COutside::FromOutside()
{
	Console::WriteLine(L"This is Outside");
}

void COutside::CInside::ShowInside()
{
	Console::WriteLine(L"-=- Inside -=-");
}

void COutside::CInside::FromInside()
{
	Console::WriteLine(L"This is inside");
}

int main()
{
    COutside ^ out = gcnew COutside;
    COutside::CInside ^ ins = gcnew COutside::CInside;

    out->ShowOutside();
    out->FromOutside();
    ins->ShowInside();
    ins->FromInside();

    Console::WriteLine();
    return 0;
}

 

 

Previous Copyright © 2006 FunctionX, Inc. Next