看到《C++ Primer》中的一句话,才想起分析一下这个问题:“static 数据成员的类型可以是该成员所属的类类型。非 static 成员被限定声明为其自身类对象的指针或引用”

  这两个问题的关键点在于static是属于类而不属于任何一个对象,这点一眼可以看出。深究细节的时候发现谭浩强版《C++ 程序设计》296页中的一段话可以辅助理解这个问题:

  “如果只声明了类而未定义对象,则类的一般数据成员是不占内存空间的,只有在定义对象时,才为对象的数据成员分配空间。但是静态数据成员不属于某一个对象,在为对象分配的空间中不包括静态数据成员所占的空间。静态数据成员是在所有对象之外单独开辟空间。只要在类中定义了静态数据成员,即使不定义对象,也为静态数据成员分配空间,他可以被引用。”

  根据这段说明,假设声明一个类:

1      class Bar {
2       private:
3           int a;
4           int b;
5           static Bar mem1; // ok
6       };   

在定义一个Bar对象A的时候,因为mem1不属于任何对象,所以A所需的空间只需关注a和b的空间,是已知可计算的值。又因mem1本身是用Bar定义的一个对象,自然它占空间的大小与A相同,只是鉴于static的成员特性,在定义任何对象之前,mem1已经存在于一个单独开辟的空间。

  标题中的第二个问题就不同,假设它的类的形式是这样的:

      class Bar2 { private: int c;int d;    Bar2 mem2; // error! };   

mem2是非static类型成员,那么使用Bar2在定义对象的时候,首先要知道该类型Bar2需要的空间,也就是说你不知道Bar2的大小,需要计算,于是,你“形象的用”int+int+Bar2(实际空间计算规则链接:相关的规则计算实际所需空间大小),显然,这其中有一个未知数,编译器计算得不到结果,自然报错。

  当“int+int+固定值”的时候,这个问题就得以解决,这时“固定值这个位置”,指针是一个不错的选择,因为指针本身占据4个字节空间,这点与它指向的对象大小无关。至于为什么“引用”也可以,那就需要了解一下“引用的本质”,在谭版《C++ 程序设计》194页有这么一句话:“声明b为a的引用,可以理解为:是变量b具有变量a的地址”,不过这句话只是点到为止,并没做更深的探讨。

2013-06-05

附录:

struct和从class的长度计算规则:

  ①在默认情况下,VC规定各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数。②各成员变量在存放的时候根据在结构中出现的顺序依次申请空间,同时按照上面的对齐方式调整位置,空缺的字节VC会自动填充。③同时VC为了确保结构的大小为结构的字节边界数(即该结构中占用最大空间的类型所占用的字节数)的倍数,所以在为最后一个成员变量申请空间后,还会根据需要自动填充空缺的字节。

  附录内容摘自:“goodfunman的博客”的《sizeof(struct var) 的长度如何计算》

转载于:https://www.cnblogs.com/tingshuixuan2012/archive/2013/05/03/3055743.html

为什么static成员的类型可以是类本身?又为什么非static成员被限定声明为其自身类对象的指针或引用?...相关推荐

  1. 成员函数对象类的const和非const成员函数的重载

    首先声明,我是一个菜鸟.一下文章中出现技术误导情况盖不负责 1. 类的const成员函数与非const成员函数的载重 #include <iostream> #include <st ...

  2. 类的const和非const成员函数的重载

    我们从一个例子说起,来看上一篇文章中的String类, 我们为它提供一个下标操作符([ ])以读写指定位置的字符(char). 只要了解过C++的操作符重载的语法,很快就可以写出下面这个[]操作符重载 ...

  3. 是否可以从一个static方法内部发出对非static方法的调用?

    *问题:是否可以从一个static方法内部发出对非static方法的调用?  *   * 答:不可以.因为非static方法是要与对象关联在一起的,必须创建一个对象后,  *         才可以在 ...

  4. C++ const对象与非const对象的相互调用、const成员函数与非const成员函数的相互调用

    1)const对象可以调用非const成员函数吗? 答:不能.const修饰的对象实则修饰的是该对象的this指针,并且const修饰的成员不能进行修改,如果使用const调用非const成员函数,可 ...

  5. 一个static方法内可以调用非static方法吗?

    不可以. 因为非 static 方法是要与对象关联在一起的,必须创建一个对象后,才可以在该对象上进行方法调用,而 static 方法调用时不需要创建对象,可以直接调用. 也就是说,当一个 static ...

  6. 2021-11-09类作为成员变量类型

    1.类作为成员变量类型 Hero.java package Demo02;public class Hero {private String name;//英雄的名字private int age;/ ...

  7. 01_11_Java语言入门||02_面向对象与常用类||day11_final、权限、内部类、成员变量类型和方法的参数及返回值特例

    第一章 final 1.1 final关键字和概念和四种用法 final关键字代表最终,不可改变的 常见四种用法 可以用来修饰一个类 可以用来修饰一个方法 可以用来修饰一个局部变量 可以用来修饰一个成 ...

  8. Java语言基础Day14(内部类、类作为成员变量类型、接口作为成员变量类型、接口作为方法的参数或返回值、红包案例、JDK9的JShell、编译器的两点优化)

    今日内容 一.内部类 1.内部类的概念与分类 2.成员内部类的定义 3.成员内部类的使用 4.内部类的同名变量访问 5.局部内部类定义 6.局部内部类的final问题 7.匿名内部类 匿名内部类定义格 ...

  9. C++ const关键字的总结(全局/局部变量、修饰指针和引用、成员函数和数据成员、修饰类对象、const与宏定义的区别、Static与Const的区别)

    const关键字 const关键字 1.什么是const 2.使用原理 2.1.const全局/局部变量 2.2.cosnt修饰指针和引用 2.3.const修饰函数参数 2.4.const修饰函数返 ...

最新文章

  1. http的“无连接”指的是_【38期】一份tcp、http面试指南,常考点都给你了
  2. 设置mysql最大连接数的方法
  3. 在Linux系统安装Nodejs
  4. 小米拒绝权限_小米手机MIUI12真有那么好吗?
  5. 奥迪坚为中民燃气打造专业便民服务呼叫中心
  6. sq工程师是做什么的_算法工程师为什么成天做数据,都做哪些数据?
  7. Git 下载、安装与SSH配置
  8. npm查找全局安装包命令
  9. Objective-C基础之基本数据类型
  10. Java学生实训平台_基于jsp的学生实训平台-JavaEE实现学生实训平台 - java项目源码...
  11. 09-排序2 Insert or Merge
  12. Internet Download Manager永久版功能强大的网络下载器
  13. Kindle Paperwhite安装PDF阅读器Koreader
  14. Editplus激活码
  15. 游戏检测到计算机性能过低,windows检测到您的计算机性能缓慢
  16. java 定时任务 单元测试_介绍java 定时任务最简单的3种实现方法
  17. 详细解析十大排序算法(js实现)
  18. Android 微信聊天记录、联系人备份并导出为表格
  19. 毕业从事弱电3个月,我为什么会选择转行网络工程师
  20. 个推技术 | 厂商和App必看!统一推送UPS最全解读和快速接入指南

热门文章

  1. 数单词 (AC自动机模板题)
  2. Yacc 与 Lex 快速入门(词法分析和语法分析)
  3. 面试算法经典书籍--编程之美
  4. golang中的优雅中止
  5. 《java多线程编程实战指南 核心篇》读书笔记二
  6. spring19:AspectJ的初步介绍
  7. 汇编:div 除法指令
  8. Android_SQLite_升级框架
  9. 使用JavaScript动态添加复选框Checkbox
  10. POSA2:Wrapper Facade模式