C++对象模型2--指针cout结果
在开始之前,首先科普一下cout指针的知识,这样才能在测试程序中很好的理解:
看下面的代码:
void main(void)
{
int a = 10;
int *p = &a; cout << a << endl;
cout << p << endl;
cout << *p << endl;
cout << &a << endl;
}
执行结果:

从代码和执行的结果可以看出cout的实现原理:cout<<后面接一个变量的标识符,然后把这个标识符转换成对应的内存地址的门牌号,然后输出这个门牌号里存储的数据。
特别地:cout<<一个指针的时候,要弄明白两件事,输出的结果是这个指针所指向的内存单元的门牌号码,同时还要弄明白这个指针变量的实际存放在内存的哪个内存单元里面。例如:cout<<p这个的输出是p指向的内存单元的门牌号,也就是a的门牌号,但是p的实际存放位置在p对应的内存空间中。
看一个复杂的模型:

- &d表示这个类对象的指针,cout<<(&d)输出的是这个对象的内存地址,这个地址原来存放在了符号表中。
- (int*)(&d)表示一个指向int类型的指针,但是这个指针的起始地址和&d是一样的,只是类型改变了。cout<<((int*)(&d))输出的值和cout<<&d是一样的。
- *(int*)(&d)表示一个指向虚函数表的指针,这个指针指向的是虚函数表的起始地址,cout<<这个指针的结果是这个指针所指向的内存单元的门牌号。同时,存储这个指针变量的内存单元是_vptr_Derived,所以得到的输出结果是存储在Derived对象中的,也就是_vptr_Derived的值。
- (int*)*(int*)(&d)+1指向虚函数表中第二个slot的指针,cout<<的结果是指向内存单元的门牌号。这个指针是计算得到的,没有内存单元存放这个指针变量的值。
- *((int*)*(int*)(&d)+1)这个指针指向void Derived::print(void) const这个函数的函数指针,但是cout这个指针的结果是这个指针所指向的内容的门牌号,但是这个指针的值实际存放的内存位置是虚函数表中的第二个slot的内容。
C++对象模型2--指针cout结果的更多相关文章
- 第51课 C++对象模型分析(下)
1. 单继承对象模型 (1)单一继承 [编程实验]继承对象模型初探 #include <iostream> using namespace std; class Demo { protec ...
- 从汇编看c++中指向成员变量的指针(一)
在c++中,指向类成员变量的指针存储的并不是该成员变量所在内存的地址,而仅仅是该成员变量在该类对象中相对于对象首地址的偏移量.因此,它必须绑定到某一个对象或者对象指针上面,这里的对象和对象指针,就相当 ...
- 全面总结sizeof的用法(定义、语法、指针变量、数组、结构体、类、联合体、位域位段)
一.前言 编译环境是vs2010(32位). <span style="font-size:18px;">#include<iostream> #inclu ...
- private成员变量真的私有吗?(用指针刨他祖坟)
今天写程序时突然想到的,为什么不用指针去获取类的成员变量呢.于是做了这个实验.首先定义了一个类: class Test { private: int i; char c; int* p; public ...
- 【C++】动态内存与智能指针
C++常见的内存分配方式有三种: 从静态存储区分配,这里主要是存储局部static对象,类的static成员以及定义在函数之外的变量: 从栈内存分配,这里主要是存储函数内的非static对象: 从堆内 ...
- [c/c++]指针数组 pk 数组指针
首先强调 指针数组归根结底是个数组:数组指针归根结底是个指针. 数组指针 以int (*int)[10]为例 ()的优先级大于[],因此首先它是一个指针,它指向一个数组,数组的维数是10.因此数组指针 ...
- c++11之智能指针
在c++98中,智能指针通过一个模板“auto_ptr”来实现,auto_ptr以对象的方式来管理堆分配的内存,在适当的时间(比如析构),释放所获得的内存.这种内存管理的方式只需要程序员将new操作返 ...
- 【C++基础】指针好难啊,一点点啃——基本概念
指针保存的是另一个对象的地址(概念真的很重要!!) ; int *ptr = &a;//*定义一个指向int类型的指针ptr, &a取变量a的地址 引用是对象的别名,多用于函数形参,引 ...
- char[]数组与char *指针的区别
char[]数组与char *指针的区别 问题描述 虽然很久之前有看过关于char指针和char数组的区别,但是当时没有系统的整理,到现在频繁遇到,在string,char[], char *中迷失了 ...
随机推荐
- shell脚本中常见的一些特殊符号和作用详解
这篇文章主要介绍了shell脚本中常见的一些特殊符号和它的作用详解,总结的很简洁,容易看懂,需要的朋友可以参考下 在编写Shell脚本时,我们需要会用到各种各样的特殊符号,通过这些特殊符号可以使我 ...
- android加载更多的图片
这是昨天改进后的,我测试了下,可以加载图片到5万张,估计5万以上也是没问题的,我只试到5万,其实也没必要这么高,现实中1000左右就差不多了,不过我的应用到100就差不多了, package com. ...
- java 集合类说明与区别
集合类说明及区别Collection├List│├LinkedList│├ArrayList│└Vector│ └Stack└SetMap├Hashtable├HashMap└WeakHashMap ...
- Ubuntu创建快捷方式
正常安装putty不成功:sudo apt-get install putty 总是报网络方面的错,我只好从官网下载源码自己编译.还是很容易的,找到unix目录,然后执行:make -f Makefi ...
- USB OTG简单介绍
1 引言 随着USB2.0版本号的公布,USB越来越流行,已经成为一种标准接口.如今,USB支持三种传输速率:低速(1.5Mb/s).全速(12Mb/s)和快速(480Mb/s),四种传输类型:块传输 ...
- S3C2440 之SPI
概述: S3C2440有两个串行外设SPI接口,SPI具有全双工通信 SPI方框图 SPI操作: 通过使用SPI接口,S3C2440可以与外部器件同时发送.接收8位数据.当SPI接口为主机时,可以通过 ...
- C语言的复合文字
假设需要向一个带有int型参量的函数传递一个值,这时可以传递一个int型常量,也可以传递一个int型的变量.在C99标准之前,数组参数情况于现在不一样,没有所谓的数组常量可供传递,而在C99中增加了复 ...
- C#反射动态赋值
很多时候我们需要在数据实体层读取数据后赋值到领域模型时往往会产生如下的代码 public class A { public string Name {get;set;} public int Age ...
- EF简介
EF:EF是 asp.net的一套ORM框架. ORM: 广义上:ORM指的是面向对象的模型和关系型数据库的数据库之间的相互转换; 狭义上:ORM可以被认为是,基于关系型数据库的数据存储,实现一个虚拟 ...
- SQL Convert XML to Table
将xml nodes 属性中的值 转为table 形式 declare @xml2 xml set @xml2 = '<CMADatas> <CMAData CmaName=&quo ...