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++确实复杂,但是我们如果利用好,复杂就是强大。

时间: 2013-11-12

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;

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

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

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下载到

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

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

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

linux中了minerd之后的完全清理过程(详解)

一不小心装了一个Redis服务,开了一个全网的默认端口,一开始以为这台服务器没有公网ip,结果发现之后悔之莫及啊 某天发现cpu load高的出奇,发现一个minerd进程 占了大量cpu,google了一下,发现自己中招了 下面就是清理过程 第一步 1.立即停止redis服务,修改端口权限,增加密码措施 2.按照网上的资料 删除 crontab 里的两个内容 sudo rm /var/spool/cron/root sudo rm /var/spool/cron/crontabs/root 3

Linux中利用sudo进行赋权的方法详解

前言 学习怎么在保护 root 密码的安全性的同时,为可信用户赋予所管理的网络功能和特定服务的权限. 我最近写了一个简短的 Bash 程序来将 MP3 文件从一台网络主机的 USB 盘中拷贝到另一台网络主机上去.拷贝出来的文件存放在一台志愿者组织所属服务器的特定目录下,在那里,这些文件可以被下载和播放. 我的程序还会做些其他事情,比如为了自动在网页上根据日期排序,在拷贝文件之前会先对这些文件重命名.在验证拷贝完成后,还会删掉 USB 盘中的所有文件.这个小程序还有一些其他选项,比如 -h 会显示

Linux中使用NTP保持精确时间的方法详解

前言 如何保持正确的时间,如何使用 NTP 和 systemd 让你的计算机在不滥用时间服务器的前提下保持同步.下面话不多说了,来一起看看详细的介绍吧. 它的时间是多少? 让 Linux 来告诉你时间的时候,它是很奇怪的.你可能认为是使用 time 命令来告诉你时间,其实并不是,因为 time 只是一个测量一个进程运行了多少时间的计时器.为得到时间,你需要运行的是 date 命令,你想查看更多的日期,你可以运行 cal 命令.文件上的时间戳也是一个容易混淆的地方,因为根据你的发行版默认情况不同,

linux中各种锁机制的使用与区别详解

前言: 相信需要了解这方面的知识的小伙伴,已经基本对进程间通信和线程间通信有了一定了解.例如,进程间通信的机制之一:共享内存(在这里不做详解):多个进程可同时访问同一块内存.如果不对访问这块内存的临界区进行互斥或者同步,那么进程的运行很可能出现一些不可预知的错误和结果. 接下来我们了解三种常见的Linux下的互斥操作->锁. 1.互斥锁(mutex) 特点:对于读者和写者来说.只要有一方获取了锁,另一方则不能继续获取,进而执行临界区代码. 创建锁: 有两种方法创建互斥锁,静态方式和动态方式.PO

Linux中如何查看已挂载的文件系统类型详解

前言 如你所知,Linux 支持非常多的文件系统,例如 ext4.ext3.ext2.sysfs.securityfs.FAT16.FAT32.NTFS 等等,当前被使用最多的文件系统是 ext4.你曾经疑惑过你的 Linux 系统使用的是什么类型的文件系统吗?没有疑惑过?不用担心!我们将帮助你.本指南将解释如何在类 Unix 的操作系统中查看已挂载的文件系统类型. 在 Linux 中查看已挂载的文件系统类型 有很多种方法可以在 Linux 中查看已挂载的文件系统类型,下面我将给出 8 种不同的

linux中如何添加用户并赋予root权限详解

一.linux添加用户并赋予root权限 1.添加用户,首先用adduser命令添加一个普通用户,命令如下: #adduser eric //添加一个名为eric的用户 #passwd eric//修改密码 Changing password for user eric. New UNIX password: //在这里输入新密码 Retype new UNIX password: //再次输入新密码 passwd: all authentication tokens updated succe

Linux中利用grep命令如何检索文件内容详解

前言 Linux系统中搜索.查找文件中的内容,一般最常用的是grep命令,另外还有egrep命令,同时vi命令也支持文件内容检索.下面来一起看看Linux利用grep命令检索文件内容的详细介绍. 方法如下: 1.搜索某个文件里面是否包含字符串 命令格式:grep "被查找的字符串" filename1 例如: grep "0101034175" /data/transaction.20170118.log 2.在多个文件中检索某个字符串 命令格式: grep &qu

Linux中让alias设置永久生效的方法详解

前言 经常使用Linux控制台终端的站长们应该对于那些繁琐的指令和参数命令行印象深刻吧!这也是很多站长宁愿使用有安全风险的面板也不愿意使用控制台终端命令行的主要原因!好在,明月早年间的DOS下学习编程的经历,对于这种命令行式的风格还是偏爱有加,但对于那些几乎经常要用到的命令行每次都要重复性的多次输入也还是烦不胜烦,记得在DOS下有.bat这样的行式批处理文件可以将那些繁琐的命令行整合管理提高效率. Linux下其实更加的方便,那就是 alias 别名命令了! 例如:原本创建文件夹的命令为 mkd

linux中rz上传、sz下载命令详解

rz,sz是便是Linux/Unix同Windows进行ZModem文件传输的命令行工具. 使用前提: 首先,你的Linux端(CentOS, Ubuntu)需要安装rz/sz命令,也就是 lszrz 包. 其次,windows端需要支持ZModem的telnet/ssh客户端(Xshell,SecureCRT支持,好像putty不支持),SecureCRT就可以用SecureCRT登陆到Unix/Linux主机(telnet或ssh均可) 运行命令rz,即是接收文件,xshell就会弹出文件选