当我查看原来写的MFC代码时,发现了一个不可思议的问题,代码如下
CMyView * CDialogViewDlg::openNewView(CMyDocument * newDoc)
{
CCreateContext pContext;
pContext.m_pCurrentDoc = newDoc;
pContext.m_pNewViewClass = RUNTIME_CLASS(CMyView);
。。。
CMyView * newView = (CMyView *)((CFrameWnd*)this)->CreateView(&pContext);
ASSERT(newView);
。。。
return newView;
}
注意代码里的(CFrameWnd*)this)->CreateView(&pContext);
我先把CDialogEx继承下来的对象指针this强制性转换成CFrameWnd*,再调用CFrameWnd类的CreateView创建View窗口,结果成功!!
我万万不解的是CDialogEx类从CWnd类继承而来,而CFrameWnd类也是从CWnd继承而来,表明CDialogEx和CFrameWnd的对象是“兄弟”关系,但怎么强制转换后就可以调用平辈的CreateView,而且还成功了?!求哪位大神帮我解释一下,谢谢!!
强制转换就是这么夸张,只要内存对上了,就能蒙对。对不上,就出各种奇怪的错误,看下面的程序
#include <iostream>
using namespace std;
class A
{
public:
int x;
void foo() { cout << "x=" << x << endl; }
};
class B
{
public:
int y;
void foo() { cout << "y=" << y << endl; }
};
int main()
{
A a;
a.x = 10;
B *b = (B *)&a;
b->foo();
return 0;
}
显然A B两个类无关,连兄弟都不算,但是就是蒙上了。
C/C++语言这种夸张的事情很多,比如明明数组越界,还能访问。还可以通过内存访问私有变量
#include <iostream>
using namespace std;
class A
{
public:
int x;
};
class B
{
private:
int x;
public:
B(int a) { x = a; }
};
int main()
{
B b(123);
A *a = (A *)&b;
cout << a->x;
return 0;
}
甚至都不要类,直接用int *都行:
#include <iostream>
using namespace std;
class B
{
private:
int x;
public:
B(int a) { x = a; }
};
int main()
{
B b(123);
cout << *((int *)&b) << endl;
return 0;
}
如果你觉得这些不可接受,你就可以放弃这种粗暴而原始的语言了。