2017-01-29 56 views
0

假設有A類和B如下:如果派生類包含其他方法和成員,static_cast是否可以從基類完成派生類?

class A 
{ 
    private: 
    int a; 

    public: 

    void seta(int a_) 
    { 
     a=a_; 
    } 
    int geta() 
    { 
    return a; 
    } 
    }; 

class B: public A 
{ 
    private: 
    int b; 

    public: 

    int getb() 
    { 
     return b; 
    } 

    void setb() 
    { 
    b=geta()+1; 
    } 

}; 

,並假設我讓這樣的代碼的功能:

A* a=new A(); 
a->seta(5); 
B* b=static_cast<B*>(a); 
b->setb(); 
cout<<b->getb()<<" and "<<b->geta()<<endl; 

此代碼編譯和運行,但是它混淆了我,爲什麼?如果a是指向A類的指針,並且在僅分配內存時爲class A成員保留(在運行時),爲什麼在靜態強制轉換後看起來該對象實際上是class B的實例。這是安全的操作嗎?

+0

我認爲這是不確定的行爲。你的第一行應該說「A和B」? – Carcigenicate

+0

我也這麼想。但它似乎有效,我不知道爲什麼? – user3616359

+2

如果您的代碼具有未定義的行爲,編譯器不需要告訴您,並且生成的程序可以執行任何操作 - 包括似乎正常工作。這並不意味着這是一個好主意。 –

回答

3

[expr.static.cast]/11,重點煤礦:

類型的prvalue「指針CV1B」,其中B是一個類型,可以轉化成類型的指針」一prvalue到CV2D 「,其中D是來自B的派生類(條款10),如果cv2cv1具有相同的cv限定或更高的cv限定。如果BD的虛擬基類或者是虛擬基類的基類D,或者如果不存在從「指向D」的指針到「指向B的指針」的有效標準轉換(4.11),則該程序不合格。空指針值(4.11)被轉換爲目標類型的空指針值。如果類型「指向cv1B」的指針的值指向實際上是D類型的對象的子對象的B,則生成的指針指向D類型的封閉對象。 否則,行爲是不確定的。

0

這不是一件安全的事。 下面的代碼說明了爲什麼

#include <iostream> 
using namespace std; 

class A 
{ 
private: 
    int a; 

public: 
    void seta(int a_) { 
    a=a_; 
    cout << "seta to: " << a << endl; 
    } 

    int geta() { 
    return a; 
    } 
}; 

class B: public A 
{ 
    private: 
    int b; 

    public: 

    int getb() { 
    return b; 
    } 

    void setb() { 
    b=geta()+1; 
    cout << "setb to: " << b << endl; 
    } 
}; 

int main() { 

    A as[2]; 

    A* a1=as; 
    A* a2=&as[1]; 

    a1->seta(5); 
    a2->seta(4); 

    cout << "a1: " 
     << a1->geta() 
     << endl; 

    cout << "a2: " 
     << a2->geta() 
     << endl; 

    B* b=static_cast<B*>(a1); 

    b->setb(); 

    a2->seta(3); 

    cout << "b->geta(): " 
     << b->geta() 
     <<" and b->getb(): " 
     << b->getb() 
     << endl; 

    size_t sizeofa(sizeof(A)); 
    cout << "sizeofa: " 
     << sizeofa 
     << endl; 

    size_t sizeofb(sizeof(B)); 
    cout << "sizeofb: " 
     << sizeofb 
     << endl; 

} 

輸出是

seta to: 5 
seta to: 4 
a1: 5 
a2: 4 
setb to: 6 
seta to: 3 
b->geta(): 5 and b->getb(): 3 
sizeofa: 4 
sizeofb: 8 
相關問題