C++中嵌套类的使用
一个类可以定义在另一个类的内部,前者称为嵌套类(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_types
int x, y; // globals
class 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.html
class 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.aspx
class 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.aspx
template <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
C++中嵌套类的使用相关推荐
- ZeroC ICE源代码中的那些事 - 嵌套类和局部类
使用嵌套类(类中定义的类,c++没有静态类)或局部类(在函数或成员方法中定义的类),进行行为模式的委托(委托请求)或异步 . java中嵌套类和局部类隐式完成了你对外部对象(实例)访问的私有堆栈的初始 ...
- python中类的嵌套_python中的嵌套类 | 学步园
在.NET和JAVA语言中看到过嵌套类的实现,作为外部类一个局部工具还是很有用的,今天在python也看到了很不错支持一下.动态语言中很好的嵌套类的实现,应该说嵌套类解决设计问题同时简化了程序,值得学 ...
- python中类的嵌套_python 中的嵌套类
嵌套类的简单介绍 在看 idarling 源码中,经常出现如下代码: import sys import ida_funcs import ida_kernwin from PyQt5.QtCore ...
- 类中嵌套子类如何JSON转换
在开发中会经常遇到一个Java类中嵌套List集合,集合中又是另外一个类,那么在Json转换的时候可能会遇到无法转换,下面这个方法就可以完美解决 public class IM_UserAccount ...
- 嵌套类可以先在外围类中声明,然后在外围类中定义
class List { private: class ListItem;//声明 class Red { ListItem *pli; //在看到类体前只能定义该 ...
- java 嵌套类 继承_Java嵌套类 - 爱吃苹果的搬运工的个人空间 - OSCHINA - 中文开源技术交流社区...
在Java中可以创建几种不同类型的嵌套类: 静态嵌套类: 静态内部类可以独立于外部类被实例化,无法访问外部类中的非静态属性和方法,只能外部类的实例来访问外部类的非静态变量 public class O ...
- Java嵌套类(Nested Classes)总结
Nested Classes定义 在java语言规范里面,嵌套类(Nested Classes)定义是: A nested class is any class whose declaration o ...
- C++知识点杂记2——类成员指针、嵌套类和union
一.类成员指针 1.概念 类成员指针指向的是类的非static成员,因为类的static成员是所有类对象共有,所以static成员的指针和普通指针没有区别 2.成员变量指针 示例 class test ...
- Java7编程 高级进阶学习笔记--嵌套类
定义: 在一个类中定义的类叫做嵌套类. 作用: 1.允许对相关类进行逻辑分组 2.增强了代码的封装性 3.使代码具有更强的可读性和维护性 使用方式: package com.cmz.baseTest; ...
最新文章
- Unity创造没有代码的游戏学习教程
- 信息系统项目管理师范围管理
- bzoj4025: 二分图
- C#编写串口通信程序(转)
- mysql普通索引自增_mysql中联合索引中的自增列的增长策略
- OpenGL:绘制太阳地球例子
- 我眼中的GaussDB——参加华为合伙伙伴赋能会有感
- PID算法C语言实现
- 手机斗鱼服务器无响应,win7看斗鱼直播很卡怎么办|win7斗鱼未响应的解决方法
- 【安卓按键精灵自动取色(可用于比色,多点找色,找图实现)】
- 事件修饰符(2) .prevent 阻止默认事件
- 你离顶尖Java程序员,只差这11本书的距离 172 分享 分享到新浪微博 分享到QQ空间
- 【保姆级】网络安全工程师学习成长路线,就业前景,薪资待遇分享
- iMazing怎么恢复备份?iMazing恢复备份教程分享
- java多人聊天室与网络画板
- HBuilder 打包 iOS 客户端会产生广告标识符的问题
- python中mainloop添加背景_Python实例讲解 tkinter canvas (设置背景图片及文字)
- SVM Kernel学习笔记
- 巨微通用无线射频芯片的功能和特点
- GOOGLE搜索高级技巧大集合
热门文章
- Tensor VS NumPy
- Pycharm报错合集:在pycharm运行anaconda配置的Pytorch环境报错(Environment location diretory is not empty )
- 基于YOLOv5模型压缩、模型量化、模型剪枝
- 【汇总记忆:命令、语法、函数、等】
- POJ - 3160 Father Christmas flymouse tanjar缩点构图+dfs
- Scrapy和MongoDB的应用
- 管理分布式session的四种方式。
- C/C++:*(p++)慎用!!!!!
- Python maketrans() 方法
- js中Array数组中的常用方法汇总