大家好!本人遇到一个问题,本人很疑惑,希望能得到大家的帮助,并帮本人指出是哪个知识点欠缺了,非常感谢。
问题概述:
多继承时,当基类有没有虚函数,有没有成员变量时,基类的this指针和子类会出现不同。例子如下:
代码如下:
问题概述:
多继承时,当基类有没有虚函数,有没有成员变量时,基类的this指针和子类会出现不同。例子如下:
代码如下:
#include <time.h> #include <stdio.h> #include <stdarg.h> #if defined(WINDOWS) #include <Windows.h> #include <process.h> #else #include <sys/time.h> #include <pthread.h> #include <unistd.h> #endif #include <string> using namespace std; bool bCanLog = false; // 从这里开始的代码都不是关键代码 inline string current_exact_time () { char szTime[128] = {0}; #if defined(WINDOWS) SYSTEMTIME st; GetLocalTime(&st); _snprintf(szTime, sizeof(szTime), "%04d-%02d-%02d %02d:%02d:%02d:%03d", st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond, st.wMilliseconds); #else time_t tmGmt = {0}; struct tm* tmBeijing = NULL; time(&tmGmt); tmBeijing = localtime(&tmGmt); timeval curTime; gettimeofday(&curTime, NULL); int mill = curTime.tv_usec / 1000; snprintf(szTime, sizeof(szTime), "%04d-%02d-%02d %02d:%02d:%02d:%03d", (1900+tmBeijing->tm_year),(1+tmBeijing->tm_mon),tmBeijing->tm_mday, tmBeijing->tm_hour,tmBeijing->tm_min,tmBeijing->tm_sec, mill); #endif return string(szTime); } inline void print_line(int line, const char* file, const char* format, ...) { if (!bCanLog) { return; } va_list args; va_start(args, format); char szBuf[2048] = {0}; vsnprintf(szBuf, 2048, format, args); va_end(args); #if defined WINDOWS int tid = GetCurrentThreadId(); #else pthread_t tid = pthread_self(); #endif int pid = getpid(); printf("[%s][%d][0x%x]: %s -- %s:%d\n", current_exact_time().c_str(), pid, tid, szBuf, file, line); } #define msg_print(...) print_line(__LINE__, __FILE__, __VA_ARGS__); #define _safe_delete(ptr) if((ptr) != 0) {delete (ptr); (ptr) = 0;} // 非关键代码结束,下面开始的都是关键代码 class org_empty_parent { public: org_empty_parent() { msg_print("org_empty_parent() \tthis[%p]", this); } }; class non_empty_parent { public: non_empty_parent() { msg_print("non_empty_parent() \tthis[%p]", this); } private: int data; }; class virtual_parent { public: virtual_parent() { msg_print("virtual_parent() \tthis[%p]", this); } virtual string get_date() = 0; }; class child_0 : public org_empty_parent { public: child_0() { msg_print("[group1]child_0() \tthis[%p]", this); } }; class child_1 : public virtual_parent { public: child_1() { msg_print("[group1]child_1() \tthis[%p]", this); } string get_date() { return current_exact_time(); } }; class child_2 : public org_empty_parent, public virtual_parent { public: child_2() { msg_print("[group1]child_2() \tthis[%p]", this); } string get_date() { return current_exact_time(); } }; class child_3 : public non_empty_parent { public: child_3() { msg_print("[group2]child_3() \tthis[%p]", this); } }; class child_4 : public non_empty_parent, public virtual_parent { public: child_4() { msg_print("[group2]child_4() \tthis[%p]", this); } string get_date() { return current_exact_time(); } }; int main (int argc, char* argv[]) { bCanLog = true; child_0 *p0 = new child_0; printf("\n--\n\n"); child_1 *p1 = new child_1; printf("\n--\n\n"); child_2 *p2 = new child_2; printf("\n--\n\n"); child_3 *p3 = new child_3; printf("\n--\n\n"); child_4 *p4 = new child_4; _safe_delete(p0); _safe_delete(p1); _safe_delete(p2); _safe_delete(p3); _safe_delete(p4); return 0; }
其中child0~child2为第一组:group1, child3~child4为第二组:group2
linux的输出结果:
可以看到:
1、多继承时,当一个基类有虚函数,另一个基类没有成员变量,全部基类和子类的this都是相同的(如group1的输出)
2、多继承时,当一个基类有虚函数,另一基类有成员变量,这个有成员变量的基类的this和子类的this就不想同了。(group2的输出)
windows的输出结果:
可以看到:
只要是多继承,其中一个基类有虚函数,另一个基类不管有没有成员变量,没有虚函数的那个基类的this和子类就不相同。(group1的child3的输出和group2的child4的输出)
本人的问题是:
1、这种不相同是什么导致的,是C++的规则还是编译器,具体是哪个知识点,该怎么解释
2、windows和linux的差异:linux只有group2参会出现this的差异,而windows的group1和2的都出现了差异,这怎么解释
本人的测试环境:
linux:
1、CentOS release 6.4 (Final)
2、gcc version 4.7.0 (GCC)
windows:
1、win 7 ultimate X64
2、VS2008 版本信息:
Microsoft Visual Studio 2008
Version 9.0.30729.1 SP
Installed Edition: Enterprise
Microsoft Visual C++ 2008 91899-153-0000007-60931
Microsoft Visual C++ 2008
解决方案
60
《深度探索C++对象模型》
《C++反汇编与逆向分析技术揭秘》
?
《C++反汇编与逆向分析技术揭秘》
?