C++中嵌套类的使用

来源:互联网 发布:mac 下 看 运行程序 编辑:程序博客网 时间:2024/05/21 09:36

一个类可以定义在另一个类的内部,前者称为嵌套类(nested class)或嵌套类型(nested type)。嵌套类常用于定义作为实现部分的类。嵌套类可用于隐藏实现细节。

嵌套类是一个独立的类,与外层类基本没什么关系。特别是,外层类的对象和嵌套类的对象是相互独立的。在嵌套类的对象中不包含任何外层类定义的成员;类似的,在外层类的对象中也不包含任何嵌套类定义的成员。

嵌套类的名字在外层类作用域中是可见的,在外层类作用域之外不可见。和其它嵌套的名字一样,嵌套类的名字不会和别的作用域中的同一个名字冲突。

嵌套类中成员的种类与非嵌套类是一样的。和其它类类似,嵌套类也使用访问限定符来控制外界对其成员的访问权限。外层类对嵌套类的成员没有特殊的访问权限,同样,嵌套类对外层类的成员也没有特殊的访问权限。

嵌套类在其外层类中定义了一个类型成员。和其它成员类似,该类型的访问权限由外层类决定。位于外层类public部分的嵌套类实际上定义了一种可以随处访问的类型;位于外层类protected部分的嵌套类定义的类型只能被外层类及其友元和派生类访问;位于外层类private部分的嵌套类定义的类型只能被外层类的成员和友元访问。

嵌套类必须声明在类的内部,但是可以定义在类的内部或者外部。当我们在外层类之外定义一个嵌套类时,必须以外层类的名字限定嵌套类的名字。在嵌套类在其外层类之外完成真正的定义之前,它都是一个不完全类型。

嵌套类和外层类是相互独立的:尽管嵌套类定义在其外层类的作用域中,但是外层类的对象和嵌套类的对象没有任何关系。嵌套类的对象只包含嵌套类定义的成员;同样,外层类的对象只包含外层类定义的成员,在外层类对象中不会有任何嵌套类的成员。

在C++11之前,嵌套类仅仅可以使用外层类的类型名、静态成员和枚举类型。但在C++11中,遵循非静态成员的通用使用规则,嵌套类可以使用外层类的任何成员。

下面是从其他文章中copy的测试代码,详细内容介绍可以参考对应的reference:

#include "nested_class.hpp"#include <iostream>#include <vector>#include <typeinfo>namespace nested_class_ {//////////////////////////////////////////////////////////// reference: http://en.cppreference.com/w/cpp/language/nested_typesint x, y; // globalsclass enclose { // enclosing classint x; // note: private membersstatic int s;public:struct inner { // nested classvoid f(int i) {//x = i; // Error: can't write to non-static enclose::x without instance//int a = sizeof(x); // Error until C++11,   // OK in C++11: operand of sizeof is unevaluated,   // this use of the non-static enclose::x is allowed.s = i;   // OK: can assign to the static enclose::s::nested_class_::x = i; // OK: can assign to global xy = i;   // OK: can assign to global y}void g(enclose* p, int i) {p->x = i; // OK: assign to enclose::x}};};class enclose_ {struct nested { // private membervoid g() {}};public:static nested f() { return nested{}; }};int test_nested_class_1(){//enclose_::nested n1 = enclose_::f(); // error: 'nested' is privateenclose_::f().g(); // OK: does not name 'nested'auto n2 = enclose_::f(); // OK: does not name 'nested'n2.g();return 0;}////////////////////////////////////////////////////////// reference: http://www.sanfoundry.com/c-tutorials-nested-structure-access//* structure A declared */typedef struct A {int a;float b;} New_a;/* structure B declared */typedef struct B {int c;float d;struct A e;    /* member 'e' is itself a structure */} New_b;int test_nested_class_2(){/* Let's declare variables of New_a and New_b */New_a bread;New_b butter;        /* 'butter' is a nested structure *//* Let's access bread using dot operator */bread.a = 10;        /* assigned member a value 10 */bread.b = 25.50;/* Let's access butter using dot operator */butter.c = 10;butter.d = 50.00;/* Let's access member 'e' which is a nested structure */butter.e.a = 20;butter.e.b = 20.00;/* Display values of members of 'butter.e' structure */printf("butter.e.a is %4d\n", butter.e.a);printf("butter.e.b is %.2f\n", butter.e.b);return 0;}////////////////////////////////////////////////////// reference: http://www.geeksforgeeks.org/nested-classes-in-c//* start of Enclosing class declaration */class Enclosing {int x;/* start of Nested class declaration */class Nested {int y;void NestedFun(Enclosing *e) {std::cout << e->x;  // works fine: nested class can access// private members of Enclosing class}}; // declaration Nested class ends here}; // declaration Enclosing class ends hereint test_nested_class_3(){return 0;}////////////////////////////////////////////////////////////// reference: http://www.oopweb.com/CPP/Documents/CPPAnnotations/Volume/cplusplus16.htmlclass Clonable {public:class Base {public:virtual ~Base() {}virtual Base *clone() const = 0;};private:Base *d_bp;public:Clonable() : d_bp(0) {}~Clonable() { delete d_bp; }Clonable(Clonable const &other) { copy(other); }Clonable &operator=(Clonable const &other){if (this != &other) {delete d_bp;copy(other);}return *this;}// New for virtual constructions:Clonable(Base const &bp){d_bp = bp.clone();      // allows initialization from}                           // Base and derived objectsBase &get() const{return *d_bp;}private:void copy(Clonable const &other){if ((d_bp = other.d_bp))d_bp = d_bp->clone();}};class Derived1 : public Clonable::Base{public:~Derived1(){std::cout << "~Derived1() called\n";}virtual Clonable::Base *clone() const{return new Derived1(*this);}};int test_nested_class_4(){std::vector<Clonable> bv;bv.push_back(Derived1());std::cout << "==\n";std::cout << typeid(bv[0].get()).name() << std::endl;std::cout << "==\n";std::vector<Clonable> v2(bv);std::cout << typeid(v2[0].get()).name() << std::endl;std::cout << "==\n";return 0;}/////////////////////////////////////////////////////////// reference: http://www.sanfoundry.com/cpp-program-illustrate-nested-classes/class Stack {class Node {public:int data;Node* next;Node(int data, Node* next);~Node();}*head;public:Stack();Stack(const Stack& s);void operator=(const Stack& s);~Stack();void push(int data);int peek() const;int pop();};Stack::Node::Node(int data, Node* next){this->data = data;this->next = next;}Stack::Node::~Node() { }Stack::Stack() { head = NULL; }Stack::Stack(const Stack& s){head = s.head;}void Stack::operator=(const Stack& s){head = s.head;}void Stack::push(int data){head = new Node(data, head);}int Stack::peek() const {if (head == 0) {std::cerr << "Stack empty!" << std::endl;return -1;}elsereturn head->data;}int Stack::pop(){if (head == NULL) return -1;int result = head->data;Node* oldNode = head;head = head->next;delete oldNode;return result;}Stack::~Stack(){if (head != NULL) {while (head->next != NULL) {Node* temp = head;head = head->next;delete temp;}}}int test_nested_class_5(){Stack Integers;int value, num;std::cout << "Enter the number of elements ";std::cin >> num;while (num > 0) {std::cin >> value;Integers.push(value);num--;}while ((value = Integers.pop()) != -1)std::cout << "Top element of stack  " << value << std::endl;return 0;}//////////////////////////////////////////////////////////////// reference: https://msdn.microsoft.com/en-us/library/71dw8xzh.aspxclass X{template <class T>struct Y {T m_t;Y(T t) : m_t(t) { }};Y<int> yInt;Y<char> yChar;public:X(int i, char c) : yInt(i), yChar(c) { }void print(){std::cout << yInt.m_t << " " << yChar.m_t << std::endl;}};int test_nested_class_6(){X x(1, 'a');x.print();return 0;}///////////////////////////////////////////// reference: https://msdn.microsoft.com/en-us/library/71dw8xzh.aspxtemplate <class T>class X_{template <class U>class Y {U* u;public:Y();U& Value();void print();~Y();};Y<int> y;public:X_(T t) { y.Value() = t; }void print() { y.print(); }};template <class T>template <class U>X_<T>::Y<U>::Y(){std::cout << "X_<T>::Y<U>::Y()" << std::endl;u = new U();}template <class T>template <class U>U& X_<T>::Y<U>::Value(){return *u;}template <class T>template <class U>void X_<T>::Y<U>::print(){std::cout << this->Value() << std::endl;}template <class T>template <class U>X_<T>::Y<U>::~Y(){std::cout << "X_<T>::Y<U>::~Y()" << std::endl;delete u;}int test_nested_class_7(){X_<int>* xi = new X_<int>(10);X_<char>* xc = new X_<char>('c');xi->print();xc->print();delete xi;delete xc;return 0;}} // namespace nested_class_

GitHub: https://github.com/fengbingchun/Messy_Test 

原创粉丝点击