c++中与继承和static相关的一些问题
大家讲道理
大家讲道理 2017-04-17 13:58:28
0
2
534
#include <iostream>

using namespace std;
class A
{
public:
    static int a;
    int b = 1;
    void test()
    {
        cout << "called A\n";
    }
};
int A::a = 10;

class B : public A
{
public:
    void test()
    {
        cout << "called B\n";
    }
};
int main()
{
    cout << B::a << endl;
    B* ptr_B = new B();
    ptr_B -> test();
    A* ptr_A = (A*)ptr_B;
    ptr_A -> test();
    cout << ptr_A << ' ' << ptr_B << endl;
    return 0;
}

代码如上,自己有几个地方比较困惑。
1.为什么static变量不能就地初始化,c++11不是就已经允许其它变量可以就地初始化吗?
2.当实例化派生类的时候,调用了基类的构造函数,那是相当于有一个匿名的基类对象被构造了吗?还是不存在这样的一个匿名对象,只是基类构造的部分是作为派生类的一部分而存在的?
3.用派生类的指针和基类的指针,当它们都是指向派生类对象的地址的时候,调用同名函数,它们的底层机制是如何实现的?为什么即便指向的是相同的地址,但是它们调用的时候却可以调用不同的函数?编译器层面是如何解释的哦?

大家讲道理
大家讲道理

光阴似箭催人老,日月如移越少年。

全部回覆(2)
PHPzhong

1, C++11以後static成員可以直接初始化,但是僅限於字面量類型(literal type).
2, 準確的說,是屬於基類的成員被初始化,並非匿名,而且這些成員也是衍生類別的一部分。
3, 這個問題比較大,你可以去了解一下C++的物件記憶體模型和virtual function的呼叫機制是怎樣的,我可以簡單的跟你介紹一下:
(1) 有虛函數裡類別裡有一個隱密的指標成員(vptr),它指向程式裡的一塊唯讀區域裡的一張虛表(vtable)。
(2) 帶有虛函數的類別經過編譯後都會有一張對應的虛表。
(3) 這個表裡存了實際上這個類別裡虛函數的實作的函數位址。
(4) 當你呼叫一個物件的虛擬函數時,程式就會從它的vptr指向的vtable來找出實際上應當呼叫的函數。

黄舟

1.只有成員變數和 static 的 const 的變數還有 enum 可以就地初始化,之所以 non-static 的不能夠就地初始化,按照 Bjarne Stroustrup 的話來說就是:

A class is typically declared in a header file and a header file is
typically included into many translation units. However, to avoid
complicated slink rules, Cunits. 🎜>definition.
That rule would be broken if C++ allowed in-class
definition of entities that needed to be stored in memory as objects.

2.作為衍生類別實例的一部分。

3.這個要分虛函數和非虛函數來考慮,你這裡的
是非虛函數,所以不會查找v-table,按照變量的類型定義來查找對應實現;如果是test()方法則會依照物件實際的類別的對應方法。編譯器層面對於你這裡的例子而言,單純的就是相當於virtualstd::bind(&B::test, ptr_B)();,所以函數實作當然是不同的了。 std::bind(&A::test, ptr_A)();

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!