2017-01-29 55 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 
相关问题