作者PkmX (阿猫)
看板C_and_CPP
标题Re: [问题] 多重继承盲点请教
时间Fri Oct 6 20:45:56 2017
居然没人回
※ 引述《dreamboat66 (小嫩)》之铭言:
: 以下是我的测试程式
: https://ideone.com/B9vCuB
: 这是main函数 想逐步询问一些观念是否有误
: int main() {
: C* ptr = new C;
: cout << "((A*)ptr):" << ((A*)ptr) << endl;
: // 这边会有一个sizeof(void*)的offset差距是因为 C中其实含有A::和B::vptr
: // 他必须shift一个offset到&B::vptr?
: cout << "((B*)ptr):" << ((B*)ptr) << endl;
基本上这是实做的细节,但原因基本上就是因为 C 里面有 A 和 B 的 vtbl 的 pointer
: ptr->A::Test(1);
: // 这边我指定B:: 所以她也是要从 "&B::vptr" 开始, 所以this 有shift offset?
: ptr->B::Test(2.2f);
如果 member function 有 qualification,
这样是直接指定要呼叫 B::Test,把 ptr 从 C* 转成 B* 当作 this 传入,
并不会有 dynamic dispatch 的功能
: ((A*)ptr)->Test(1);
: //这边我不太能理解 他为什麽能够把this "退回" 到 ptr 而不是 (B*)ptr?
: ((B*)ptr)->Test(2.2f);
这就跟你写 B* b = ptr; b->Test(0.0f); 一样的道理
: //刻意转成void*
: void* ptrA = ((A*)ptr);
: void* ptrB = ((B*)ptr);
: ((A*)ptrA)->Test(1);
: // 我可以解读说 他在B::vptr指向的vtable中找Test 是C::有override
: // 所以她知道要"退回"到ptr?
: ((B*)ptrB)->Test(2.2f);
你这边等於先用 static_cast 把 C* 变成 B*,
再用 reinterpret_cast 将 B* 转成 void*,
然後再用一次 reinterpret_cast 将 void* 转成 B*,
後面两个基本上是抵销掉没有用处的,
所以这个例子和上面的 ((B*) ptr)->Test(2.2f) 一样
: // 这边故意写错, 是不是就让他去A::vptr里面找错vtable所以Test就走到
: // A::Test(int)被C::Test给override的版本?
: ((B*)ptrA)->Test(2.2f);
C* -> B* -> void* -> A* 的最後一个 reinterpret_cast 是 undefined behavior (UB)
: // 这边我只是想要确认一下override 两个不相干却同名字的virtual function
: // 是不是A::Same跟B::Same同时都会被override 并且也没有写法能够让他们走
: // 不同的实作?
: // 如果观念没错 是不是 A::vptr 和B::vptr 所指向的vtable里面分别都有
: // Same的entry(想确定是不是有两份override)
是的,如果要 override 相同 signature 的函式但是不同实做,有一个方法:
struct a { virtual int f() = 0; };
struct b { virtual int f() = 0; };
struct a_impl : a { virtual int f() override { return 1; } };
struct b_impl : b { virtual int f() override { return 2; } };
struct c : a_impl, b_impl {};
c x;
static_cast<a&>(x).f(); // 1
static_cast<b&>(x).f(); // 2
: ((A*)ptrA)->Same();
: ((B*)ptrB)->Same();
: ((B*)ptrA)->Same();
最後这个是 UB,原因同上
: ptr->Same();
: return 0;
: }
: 以上是我自己解读的, 如果有错误, 请各位矫正一下观念
: 谢谢
大guy就是这样
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 140.113.193.217
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1507293958.A.01D.html
1F:推 dreamboat66: 谢谢你 我大概了解了 多了一些认识 10/06 21:52
※ 编辑: PkmX (140.113.193.217), 10/06/2017 22:29:56
2F:推 dreamboat66: 所以不做static_cast<a&>(x).f() ,直接使用x.f()会am 10/08 02:44
3F:→ dreamboat66: biguity? 10/08 02:44
4F:→ PkmX: 会 因为 c 里面有两份 f() 10/08 02:51