大家好!本人遇到一个问题,本人很疑惑,希望能得到大家的帮助,并帮本人指出是哪个知识点欠缺了,非常感谢。
问题概述:
多继承时,当基类有没有虚函数,有没有成员变量时,基类的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++反汇编与逆向分析技术揭秘》
?