抽象类中的this到底指的是哪个子类实例呢?请看代码:

thread.h

#ifndef __THREAD_H__
#define __THREAD_H__#include <iostream>#define PATTERN_SINGLETON_DECLARE(classname)   \
private:                                        \classname();                               \
public:                                         \static classname * instance();             \virtual ~classname();#define PATTERN_SINGLETON_IMPLEMENT(classname)    \
classname * classname::instance()               \
{                                               \static classname * _instance = NULL;      \if( NULL == _instance)                       \{                                          \_instance = new classname;                \}                                          \return _instance;                          \
}class CThread
{friend void ThreadBody(void *pdat);public:CThread();~CThread();bool CreateThread();virtual void ThreadProc(const std::string &name) = 0;protected:bool m_bLoop;std::string m_name;
};class CCaptureManager: public CThread
{PATTERN_SINGLETON_DECLARE(CCaptureManager)
public:void start();private:void ThreadProc(const std::string &name);private:int m_pid;
};#define g_captureManager (*CCaptureManager::instance())class CCaptureManager2: public CThread
{PATTERN_SINGLETON_DECLARE(CCaptureManager2)
public:void start();private:void ThreadProc(const std::string &name);
};#define g_captureManager2 (*CCaptureManager2::instance())#endif

thread.cpp

#include <stdio.h>
#include "thread.h"PATTERN_SINGLETON_IMPLEMENT(CCaptureManager)void ThreadBody(void *pdat)
{CThread *pThread = (CThread *)pdat;//pThread->ThreadProc();pThread->ThreadProc(pThread->m_name);
}CThread::CThread()
{m_bLoop = true;m_name = "Base";printf("CThread-this=%x, name=%s\n", this, m_name.c_str());
}CThread::~CThread()
{}bool CThread::CreateThread()
{printf("CThread::CreateThread-this=%x, m_bLoop=%d\n", this, m_bLoop);ThreadBody(this);     // 这里的this为具体对象实例的指针return true;
}CCaptureManager::CCaptureManager()
{m_pid = 10;m_name = "CCaptureManager";printf("CCaptureManager-this=%x, m_bLoop=%d\n", this, m_bLoop);
}CCaptureManager::~CCaptureManager()
{}void CCaptureManager::start()
{printf("%s()\n", __FUNCTION__);CreateThread();
}void CCaptureManager::ThreadProc(const std::string &name)
{printf("CCaptureManager::ThreadProc()-%dL, name=%s------\n", __LINE__, name.c_str());
}PATTERN_SINGLETON_IMPLEMENT(CCaptureManager2)CCaptureManager2::CCaptureManager2()
{m_name = "CCaptureManager2";printf("CCaptureManager2-this=%x\n", this);
}CCaptureManager2::~CCaptureManager2()
{}void CCaptureManager2::start()
{printf("%s\n", __FUNCTION__);CreateThread();
}void CCaptureManager2::ThreadProc(const std::string &name)
{printf("CCaptureManager2::ThreadProc()-%dL, name=%s------\n", __LINE__, name.c_str());
}

a.cpp

#include <iostream>
#include <typeinfo>
#include "thread.h"using namespace std;int main()
{cout << sizeof(CThread) << ", " << sizeof(CCaptureManager) << ", " << sizeof(CCaptureManager2) << endl;    // 12, 16, 12g_captureManager.start();cout << "--------------------------\n\n";g_captureManager2.start();cout << typeid(g_captureManager).name() << endl;cout << typeid(g_captureManager2).name() << endl;cout << typeid(CCaptureManager).name() << endl;if(typeid(g_captureManager) == typeid(CCaptureManager))cout << "true" << endl;elsecout << "false" << endl;return 0;
}/*
运行情况:
D:\profile\Desktop\test1>make
g++ -o a.exe a.cpp thread.cppD:\profile\Desktop\test1>a
12, 16, 12
CThread-this=692a70, name=Base                                    // 基类构造函数: CThread::CThread()
CCaptureManager-this=692a70, m_bLoop=1                            // CCaptureManager构造函数
start()                                                         // CCaptureManager::start()
CThread::CreateThread-this=692a70, m_bLoop=1                  // CThread::CreateThread()
CCaptureManager::ThreadProc()-53L, name=CCaptureManager------  // CCaptureManager->ThreadBody()
--------------------------CThread-this=692a88, name=Base                                  // 基类构造函数: CThread::CThread()
CCaptureManager2-this=692a88                                   // CCaptureManager2构造函数
start                                                           // CCaptureManager2::start()
CThread::CreateThread-this=692a88, m_bLoop=1                  // CThread::CreateThread()
CCaptureManager2::ThreadProc()-78L, name=CCaptureManager2------    // CCaptureManager2->ThreadBody()15CCaptureManager
16CCaptureManager2
15CCaptureManager
true注: 虽然在创建CCaptureManager和CCaptureManager2的实例时,都调用了基类的构造函数,但是从输出的结果可以看出: this的值是不一样的, 而且都等于实例中的this!*/

在linux下用g++编译和在windows上用vc6编译,得到typeid()的输出不一样,这可能是由于具体的实现不同导致的!以实际运行环境为准!

在vc6中要启用RTTI支持,具体见:http://blog.csdn.net/joeblackzqq/article/details/9281705

纯虚函数--抽象类中的this到底指的是哪个子类实例呢相关推荐

  1. 栈内存 ,堆内存区别 C++ 动态内存 == 与equal区别 复合函数奇偶性 三角函数转换公式: 虚函数和纯虚函数: C++ 中的运算符重载 数据封装,数据抽象 C++ 接口(抽象类

    目录 栈内存 ,堆内存区别 C++ 动态内存 == 与equal区别 复合函数奇偶性 三角函数转换公式: 虚函数和纯虚函数: C++ 中的运算符重载 数据封装,数据抽象 C++ 接口(抽象类): #和 ...

  2. C++ 虚函数 纯虚函数 抽象类 代码示例

    其中抽象类指的是在类的定义中出现了纯虚函数,导致无法实例化,. 代码:头文件 #include "stdafx.h"using namespace std;class Person ...

  3. C++中的各种“虚“-- 虚函数、纯虚函数、虚继承、虚基类、虚析构、纯虚析构、抽象类讲解

    C++中的各种"虚" 1. 菱形继承 1.1 虚继承 && 虚基类 1.2 虚基类指针(vbptr)&& 虚基类表(vbtable) 2. 多态 2 ...

  4. C++多态(二)——纯虚函数、抽象类

    本篇涉及内容: 纯虚函数 抽象类 纯虚函数: 1)应用场景: 在多态中,通常父类中的虚函数是无意义的,一般情况下都会被子类重写,此时可以将父类中的这些虚函数改为纯虚函数. 2)纯虚函数语法:virtu ...

  5. 纯虚函数 和 抽象类

    纯虚函数:虚函数,有时并不是基类本身的要求,而是考虑到派生类的需要,在基类中预留了一个函数名. 纯虚函数的作用:基类类型的指针,如果指向的是派生类的对象,那么它就可以访问这个函数,从而执行的是派生类中 ...

  6. cc32a_demo-32dk2j_cpp_纯虚函数与抽象类-txwtech

    //32dk2j_cpp_纯虚函数与抽象类cc32a_demo-txwtech //纯虚函数是用来继承用的 //纯虚函数 //抽象类-抽象数据类型 //*任何包含一个或者多个纯虚函数的类都是抽象类 / ...

  7. c++ 虚函数多态、纯虚函数、虚函数表指针、虚基类表指针详解

    文章目录 静态多态.动态多态 虚函数 哪些函数类型不可以被定义成虚函数? 虚函数的访问方式 析构函数中的虚函数 虚函数表指针 vptr 多继承下的虚函数表 虚基类表指针 bptr 纯虚函数 抽象类 虚 ...

  8. C++_虚继承_虚函数_纯虚函数(多继承的二义性,多态)

    基本信息 每一个类都有一个虚表,以及虚表指针; 虚表的内容是编译器决定的,虚表中用于存放虚函数的指针, 程序运行时的类型信息等; 每个多态对象都存放着一个指向当前类型的虚表的指针, 该指针在构造函数中 ...

  9. 一口气搞懂《虚函数和纯虚函数》

    学习C++的多态性,你必然听过虚函数的概念,你必然知道有关她的种种语法,但你未必了解她为什么要那样做,未必了解她种种行为背后的所思所想.深知你不想在流于表面语法上的蜻蜓点水似是而非,今天我们就一起来揭 ...

最新文章

  1. Java中Queue和BlockingQueue的区别
  2. 2020 最烂密码 TOP 200 大曝光,霸榜的竟然是它?
  3. mysql 字符串大小写_Mysql 字符串类型及大小写
  4. 采用邻接表存储结构,编写一个判别无向图中任意给定的两个顶点之间是否存在一条长度为k的简单路径的算法。
  5. 服务器配置文件salt,saltstack 配置文件详解
  6. SAP Spartacus Theme 设置
  7. cad线性标注命令_CAD常用标注快捷键和命令
  8. 2019.01.24【NOIP普及组】模拟赛C组
  9. java 中创建数据端口_java 如何在服务器端用socket创建一个监听端口,并对接受的数据进行处理,端口号为3333,请高手指点一下...
  10. suse 查看java版本_SLES 11 中JDK的安装和配置
  11. 配置eclipse编写html/js/css/jsp/java时自动提示
  12. 被踢出sci_这本世界上创刊最早的期刊竟被踢出 SCI 了?!
  13. 如何制作/输入 英语/美语音标
  14. [置顶] 博客停止更新 我的大学数年
  15. 2021鹏业安装算量软件常见问题整理(十六)
  16. php制作特效文字,PPT制作文字特效 PPT特效文字制作教程
  17. C++后台开发面试常考
  18. 正则表达式 -文书网ktr
  19. Mybatis映射详解
  20. 快讯 | 第80届金球奖揭晓

热门文章

  1. 重写Checkbox 改写选择框的大小
  2. Anton Chuvakin:关于日志管理产品的十个注意事项
  3. 数据挖掘流程_数据流挖掘
  4. Java里面的静态代码块
  5. 按钮提交在url后添加字段_在输入字段上定向单击“清除”按钮(X)
  6. 播客51:妈妈可以编码的创始人埃里卡·彼得森(Erica Peterson)
  7. htt://3g.hn_根据我对“询问HN:谁在招聘?”的分析,开发人员技能发展趋势
  8. 机器人的动力学和动力学联系_通过机器学习了解幸福动力学(第2部分)
  9. java及python调用RabbitMQ
  10. java 的 == 和equals()区别