C++调试追踪class成员变量的方法

比如:int (*foo)(int arg),记住要和另一个指针函数区分开来,类似这样:int *foo(int arg).
比如我们可以这样声明一个变量和函数:

代码如下:

int (*pfun)(int arg)=0;
int fun(int arg);    //这个函数实现随便啦,我就不写了。

如果我们想利用函数指针操作函数,就和指针变量使用一样:


代码如下:

pfun=fun;
int result=(*pfun)(123);

对,很鸡肋也没必要。这是当然,因为我们没用在对的地方。下面我要讲的是利用一个类去call back另一个无关类的成员。

代码:

代码如下:

#include <iostream>
using namespace std;
template<typename T,typename N>
class Functor{
public:
   Functor(T *otherp,N (T::*otherfun)(N arg))
   {
       mp=otherp;
       mfun=otherfun;
   }
   virtual N operator()(N arg)
   {
       return (*mp.*mfun)(arg);
   }
private:
   N   (T::*mfun)(N arg);
   T *mp;
};
class A{
public:
    A(int a0):a(a0){}
    int traced(int b)
    {
        cout<<"Trace a="<<a<<",b="<<b<<endl;
        return 0;
    }
private:
    int a;
};
int main()
{
    A a(10);
    Functor<A,int> trace(&a,&A::traced);
    trace(5);
    return 0;
}

第33行把class A的成员函数地址传给了Functor的函数指针,从而能够通过Functor的成员处理A中的成员。
这里用到了对operator()的重载,可以换成别的函数处理Functor的函数指针
(不处理也行,但是函数指针很绕人,不直观),像这样:

代码如下:

#include <iostream>
using namespace std;
template<typename T,typename N>
class Functor{
public:
   Functor(T *otherp,N (T::*otherfun)(N arg))
   {
       mp=otherp;
       mfun=otherfun;
   }
   virtual N out(N arg)         //改动
   {
       return (*mp.*mfun)(arg);
   }
private:
   N   (T::*mfun)(N arg);
   T *mp;
};
class A{
public:
    A(int a0):a(a0){}
    int traced(int b)
    {
        cout<<"Trace a="<<a<<",b="<<b<<endl;
        return 0;
    }
private:
    int a;
};
int main()
{
    A a(10);
    Functor<A,int> trace(&a,&A::traced);
    trace.out(5);      //改动
    return 0;
}

C++确实复杂,但是我们如果利用好,复杂就是强大。

(0)

相关推荐

  • Linux中使用VS Code编译调试C++项目详解

    前言 关于VS Code在Linux下的安装这里就不提了,不管是CentOS还是Ubuntu,如果不懂且搜问题足够的情况下,你会解决的. 一.前置知识--gcc/g++的编译链接过程 在Windows下,如果你用Visual Studio进行开发,C/C++的编译器一般采用微软提供的MSBuild:在Linux下C/C++的编译器大多采用gcc/g++.既然要在Linux下进行C++开发,很有必要了解一下g++编译器的一些基本知识. 假设我现在有一个最简单的C++文件: #include <io

  • C++的try块与异常处理及调试技术实例解析

    本文以示例形式简述了C++ try块的异常处理与调试技术,有助于读者复习并加深对try块的了解. 一.格式: 抛出异常throw 异常类型例如throw runtime_error("Data must refer to same ISBN"); try{ program-statements }catch(exception-specifier) { handler-statement; }catch(exception-specifier) { handler-statement;

  • C++调试记录与心得分享

    之前开发用Linux C比较多,C++中的STL 容器基本没有接触过.最近在学习C++,平时用到c++ 17中的部分新特性,下面就简单分享下自己C++的学习流程. 一.环境搭建 本人使用的是CentOS 7系统,该系统默认的g++版本不支持c++17的新特性.所以,首先需要做的就是升级新版本的g++. 1.到ftp://ftp.mirrorservice.org/sites/sourceware.org/pub/gcc/releases/网站上选择支持c++17的gcc版本,并使用wget下载到

  • 如何利用Emacs来调试C++程序

    俗话说,Emacs是神的编辑器,而Vim是编辑器之神.高手程序员都是用这两样神器进行开发.本人觉得,Emacs之所以厉害,是因为许多在其他编辑器下必须用鼠标点选很多步的操作,在Emacs下都可以通过键盘来完成.大大地节省了你在显示器上找按钮的时间.Emacs在Linux上运行感觉比windows流畅些,用Emacs编辑程序时,手基本不用离开键盘,就可以完成所有的工作.那么今天就让我们看看如何利用Emacs来调试C++程序. 一.安装Emacs和GCC 下载地址:Emacs:http://www.

  • C++软件添加dump调试打印日志(推荐)

    C++软件添加dump调试打印日志(推荐) #include <DbgHelp.h> #pragma comment(lib, "dbghelp.lib") LONG WINAPI TopLevelExceptionFilter(struct _EXCEPTION_POINTERS *pExceptionInfo) { //cout << "Enter TopLevelExceptionFilter Function" << en

  • C++调试追踪class成员变量的方法

    比如:int (*foo)(int arg),记住要和另一个指针函数区分开来,类似这样:int *foo(int arg).比如我们可以这样声明一个变量和函数: 复制代码 代码如下: int (*pfun)(int arg)=0;int fun(int arg);    //这个函数实现随便啦,我就不写了. 如果我们想利用函数指针操作函数,就和指针变量使用一样: 复制代码 代码如下: pfun=fun;int result=(*pfun)(123); 对,很鸡肋也没必要.这是当然,因为我们没用在

  • Java面向对象基础,类,变量,方法

    一.面向对象的4个基本特征 抽象性.封装性.继承性和多态性. 抽象性分为过程抽象和数据抽象. 封装性 封装将数据以及加在这些数据上的操作组织在一起,成为有独立意义的构件.外部无法直接访问封装的数据,从而保证了这些数据的正确性. 如果外部需要访问类里面的数据,就必须通过接口.接口规定了可对一个特定的对象发出哪些请求. 继承性 继承是一种联结的层次模型,并允许和鼓励类的重用,它提供给了一种明确表述共性的方法.对象的一个新类可以从现有的类中派生,这个过程称为类继承.新类继承了原始类的特性,新类称为原始

  • c++访问私有private成员变量的常用方法

    类的对象不能直接访问类声明的私有成员变量,否则破坏了信息隐藏的目的. 在C++中,为了防止某些数据成员或成员函数从外部被直接访问,可以将它们声明为private,这样编译器会阻止任何来自外部非友元的直接访问. 私有成员变量的常用访问方法如下: (1)通过公共函数为私有成员赋值 #include <iostream> using namespace std; class Test { private: int x, y; public: void setX(int a) { x=a; } voi

  • c++ 类中const成员变量的赋值方法

    在头文件的类的定义中定义了一个const成员变量c++ 规则: 1.类定义中不能进行初始化,因为头文件中类的定义只是一个声明,并没有分配真正空间,因此变量是不存在的,因此是不能赋值的. 2.const 定义的变量是不能赋值 这可如何是好,声明中不能赋值,声明完还不能赋值.又不能不赋值. 解决方案: 1.在构造函数后的参数初始化列表中初始化 2.将const变量同时声明为 static 类型进行初始化. Eg: #include <iostream> class CTestA { public:

  • 对Python 获取类的成员变量及临时变量的方法详解

    利用Python反射机制,从代码块中静态获取参数: co_argcount: 普通参数的总数,不包括参数和*参数. co_names: 所有的参数名(包括参数和*参数)和局部变量名的元组. co_varnames: 所有的局部变量名的元组. co_filename: 源代码所在的文件名. co_flags: 这是一个数值,每一个二进制位都包含了特定信息.较关注的是0b100(0x4)和0b1000(0x8),如果co_flags & 0b100 != 0,说明使用了*args参数:如果co_fl

  • runtime获取属性和成员变量方法

    成员变量 1.成员变量的定义 Ivar: 实例变量类型,是一个指向objc_ivar结构体的指针 typedef struct objc_ivar *Ivar; 2.相关函数 // 获取所有成员变量 class_copyIvarList // 获取成员变量名 ivar_getName // 获取成员变量类型编码 ivar_getTypeEncoding // 获取指定名称的成员变量 class_getInstanceVariable // 获取某个对象成员变量的值 object_getIvar

  • Java中方法的重写与成员变量的隐藏

    这篇文章讨论了Java面向对象概念中一个基本的概念–Field Hiding(隐藏成员变量) 在讨论这个问题之前,我们看一段特别特别简单的代码,请问一下方法的数据结果是什么? /** * @author Hollis 17/9/27. */ public class FieldOverriding { public static void main(String[] args) { Sub c1 = new Sub(); System.out.println(" c1.s : " +

  • 浅析Java中局部变量与成员变量同名解决技巧

    要想区分这哥俩,首先,我们得知道它们分别是什么.先从成员变量下刀. 成员变量 我们来研究一个事物: 属性:外在特征:例如人的身高,体重 行为:能够做什么:例如人有说话,打球等行为. 而在Java语言中,最基本的单位是类,类就是用来体现事物的. 用类class来描述事物也是如此: 属性:对应类中的成员变量 行为:对应类中的成员函数 定义类其实就是在定义类中的成员(成员变量和成员函数) 拓展:类是一个抽象的概念,而对象就是类的具体的存在,体现.例如:生活中的汽车,可以看做一个类,我们称之为汽车类,每

  • 浅谈静态变量、成员变量、局部变量三者的区别

    静态变量和成员变量的区别: A:所属不同 静态变量:属于类,类变量    成员变量:属于对象,对象变量,实例变量 B:内存位置不同 静态变量:方法区的静态区    成员变量:堆内存 C:生命周期不同 静态变量:静态变量是随着类的加载而加载,随着类的消失而消失    成员变量:成员变量是随着对象的创建而存在,随着对象的消失而消失 D:调用不同 静态变量:可以通过对象名调用,也可以通过类名调用    成员变量:只能通过对象名调用 成员变量和局部变量的区别: A:在类中的位置不同 成员变量:在类中方法

  • PHPLog php 程序调试追踪工具

    原理: 1.程序执行的过程中,在相应的地方记录你想要追踪的变量及调用栈和每次函数调用的参数,          把这些信息以一定的格式记录到文件,一个变量一行,具体数据格式请参看代码,这里不细讲. 2.现在有了每次记录变量时的所有信息(包括调用栈及参数),当你通过浏览器访问这个程序时, 这个程序会把整个文件读取分析,          在页面显示你的所有调试信息,并且它会动态ajax刷新,保持与你的调试同步. 画个图吧,要清晰得多.      BackTrace也就是调用栈信息,没有在图中体现,

随机推荐