类成员指针——偏移量

  成员指针只是记录一个成员的偏移量,而非地址,因为类中没有地址,选择一个类的成员只是意味着在类中偏移,只有把这个偏移和具体对象的首地址结合,才能得到实际地址。

  成员指针并不指向一个具体的内存位置,它指向的是一个类的特定成员,而不是指向一个特定对象的特定成员,最直接的理解是将其理解为一个偏移量。这个偏移量适用于某一类A的任何对象,换言之,如果一个A类对象的成员a距离起点的偏移量是4,那么任何其他A类对象中,a的偏移都是4字节。

  1. 类对象访问其成员时,是根据该成员在类中的偏移量来访问的。
  2. 类成员指针,可以理解为指向类数据成员的一个偏移量,而非地址。
#include<stdio.h>
#include<string.h>
#include <iostream>
using namespace std;
class A
{
public:
    A() {m_a = 1; m_b = 2;}
    ~A() {}
    void fun() {printf("%d %d", m_a, m_b);}
public:
    int m_a;
    int m_b;
};
class B
{
public:
    B() {m_c = 3;}
    ~B() {}
    void fun() {printf("%d", m_c);}
public:
    int m_c;
};
int main()
{
    A a;
    B *pb = (B*)(&a);
    pb->fun();             //1 m_a的值
    cout << &a << endl;          //0012FF6C 对象a的首地址
    cout << &(a.m_a) << endl;   //0012FF6C 对象成员m_a的首地址,也就是对象a的首地址
    cout << &(a.m_b) << endl;   //0012FF70
    printf("%p\n",&A::a.m_a);   //00000000 偏移量
    printf("%p\n",&A::a.m_b);   //00000004 偏移量
    printf("%p\n",&B::a.m_c);   //00000000 偏移量
    cout << &A::a.m_a << endl;  //1 输出成员指针的值,最好使用printf,%p输出指针
    cout << &A::a.m_b << endl;  //1 输出成员指针的值,最好使用printf,%p输出指针
    return 0;
}

输出成员指针的值,最好使用printf,%p输出指针!

使用语句


1

cout<<&A::m_a<<&A::m_b;

结果全是1。

  究其原因,应该是ostream对象没有重载类成员指针的参数,故不能直接输出类成员指针的类型,而我们知道指针类型与bool类型的转换属于标准转换的(常常用来测试指针合法性是否为空),而ostream对象可以输出bool类型,故编译器将成员指针类型转换成了bool类型,从而输出,既然这样为什么全是输出1呢?说明地址全是合法的,即偏移量全是大于0,不对呀,第一个类成员的偏移量不是0么,这里真心不明白,不过《C++必知必会》中有这样一句话:大多数编译器都将成员指针实现为一个整数,包含被指向成员的偏移量,另外加上1(加1是为了让值0可以表示一个空的数据成员指针)。这大概就是全输出1的原因了吧。

时间: 2024-08-25 20:18:31

类成员指针——偏移量的相关文章

C++拾遗--类成员指针

C++拾遗--类成员指针 前言 类成员的类型与一般类型不同,那么类成员的指针类型自然与一般类型的指针有所区别.我们有必要来探讨下类成员指针的使用. 正文 类成员指针是指可以指向类的非静态成员的指针.它的类型包括了类类型和所指向的成员类型.一般而言,指针指向的是对象,而类成员指针指向的是类成员而非类对象. 需要指出,类成员指针不是可调用对象,要想通过类成员指针调用类成员,需结合类对象或类指针.静态类型成员属于类,类型与普通指针相似. 数据成员指针 一般的声明形式: 成员类型 classname::

C++ Primer 学习笔记_103_特殊工具与技术 --类成员指针

特殊工具与技术 --类成员指针 成员指针可以做到:获得特定成员的指针,然后从一个对象或别的对象获得该成员.成员指针应该包含类的类型以及成员的类型. 一.声明成员指针 测试类: class Screen { public: typedef std::string::size_type index; char get() const; char get(index ht,index wd) const; private: std::string contents; index cursor; ind

[C++ primer]类成员指针

1.声明成员指针 有时我们希望直接获取成员的指针,然后从一个对象或别的对象获得该成员,这时就需要用到成员指针.成员指针,包含类的类型以及成员的类型. 成员指针只针对类的非static成员.static类成员不是任何对象的组成部分,所以不需要特殊语法来指向static成员,static成员指针是普通指针. 注:它指向的是一个类的特定成员,而不是指向一个特定对象里的特定成员. 成员指针的定义格式:成员类型 类名::*指针名=&类名::成员名; 成员函数指针的定义格式: 成员函数返回类型 类名::*指

类成员指针

数据成员指针 成员指针是指可以指向非静态成员的指针,成员指针指示的是类的成员,而非类的对象.类的静态成员不属于任何对象,因此无须特殊的指向静态成员指针,指向静态成员的指针与普通的指针没有什么区别. class Screen { public: typedef std::string::size_type pos; char get_cursor() const { return contents[cursor]; } char get() const; char get(pos gt, pos

C++ Primer 笔记——类成员指针

1.当我们初始化一个成员指针或为成员指针赋值时,该指针并没有指向任何数据.成员指针指定了成员而非成员所属的对象,只有当解引用成员指针时,我们才提供对象信息. 2.和普通的函数指针类似,如果成员存在重载的问题,则我们必须显示地声明函数类型以明确指出我们想要使用的是哪个函数.和使用指向数据成员的指针一样,我们使用 .* 或者 ->*运算符作用于指向成员函数的指针. class test { public: void Add(int){} void Add(long){} void get() {}

类成员的指针

ps:const对象只能调用const函数!!非const对象随便!! 成员指针只应用于类的非 static 成员.static 类成员不是任何对象的组成部分,所以不需要特殊语法来指向 static 成员,static 成员指针是普通指针. int *p = &Screen::total;    (total 是 static int total;) 例子: #include<iostream> using namespace std; class Screen{ public: st

类成员函数的指针与多态性

1 类成员函数的指针 2 类成员函数的指针数组 3 指向类成员函数的指针的指针 1 类成员函数的指针 auto func1 = &com::jia;//C++函数指针 int (com::*p)(int, int) = &com::jia;//C函数指针 1 #include <iostream> 2 3 class com 4 { 5 private: 6 int a; 7 int b; 8 public: 9 com(int x, int y) :a(x), b(y) 10

C++的继承操作---基类指针访问派生类问题---基类成员恢复访问属性问题

#include "stdafx.h" #include <iostream> #include <algorithm> using namespace std; class Base { public: int num; virtual void func() { cout<<"Do something in Base"<<endl; } }; class Derived:private Base { public:

C++中如何获取类成员的指针

 我们都知道C++ class中有三种成员函数,static(静态的),nonstatic(非静态的),virtual(虚拟的)各种成员函数的指针各有区别,以下是一个完整的例子:(注意红颜色的区别) class A { public: static void staticmember(){cout<<"static"<<endl;}   //static member void nonstatic(){cout<<"nonstatic&