2016-03-17 117 views
1

在講座期間,一些學生表示這種上傳和下調缺乏邏輯性,並且是非法的。有些老師感到困惑和同意,並表示他會再次審查和做講座,但我不知道這段代碼有什麼問題,並且有沒有這種情況是非法的。什麼使上傳和非法下載

#include <iostream> 
using namespace std; 
class base { 
public: 
     int a,b; 
     base(){ 
     a=0; 
     b=1;} 
}; 
class derived : public base { 
public: 
    int c,d; 
    derived(){ 
    c=2; 
    d=3; 
    } 
}; 
int main(){ 
    derived der; 
    base baseob; 
    derived *derptr=new derived; 
    derptr=(derived*)&baseob; 
    base *baseptr=new base; 
    baseptr=&der; 
} 

編輯: 刮開上面的代碼是什麼我工作,但就像是指出了內存泄漏發生(愚蠢的我沒有看到),這裏是新的代碼,現在我只希望知道它是否合法? (動態演員陣容後,這使動態轉換的沒有例子被教導請)

#include <iostream> 
using namespace std; 
class Employee 
{ 
public: 
Employee(string fName, string lName, double sal) 
{ 
FirstName = fName; 
LastName = lName; 
salary = sal; 
} 
string FirstName; 
string LastName; 
double salary; 
void show() 
{ 
cout << "First Name: " << FirstName << " Last Name: " << LastName << " Salary: " << salary<< endl; 
} 
void addBonus(double bonus) 
{ 


salary += bonus; 
} 
}; 
class Manager :public Employee 
{ 
public: 
Manager(string fName, string lName, double sal, double comm) :Employee(fName, lName, sal) 
{ 
Commision = comm; 
} 
double Commision; 
double getComm() 
{ 
return Commision; 
} 
}; 

對於向下轉型

int main() { Employee e1("Ali", "Khan", 5000); //object of base class 
    //try to cast an employee to 
    Manager Manager* m3 = (Manager*)(&e1); //explicit downcasting 
    cout << m3->getComm() << endl; return 0; } 

對於上溯造型

int main() 
    { 
    Employee* emp; //pointer to base class object 
    Manager m1("Ali", "Khan", 5000, 0.2); //object of derived class 
    emp = &m1; //implicit upcasting 
    emp->show(); //okay because show() is a base class function 
    return 0; 
    } 
+2

存在內存泄漏,因爲您通過調用'new'來獲得內存,但是您不會爲空閒指針調用'delete'。此外,在將其設置爲本地對象後,指針會丟失:'derptr =(derived *)&baseob;'和'baseptr = &der;'。這是非常錯誤的!上傳和下載無論在這裏。你應該閱讀C++中的'new'和'delete'和'pointers'。 – nikniknik2016

+1

只有一個cast,即下降的'(derived *)&baseob',它不合法,因爲'baseob'不是'derived'。 'baseptr =&der'是有效的,但不是演員。 – molbdnilo

+0

@molbdnilo,它不是C++定義的「cast」,但它是一個隱式的upcast,即使它不是一個正式的C++術語,它也是常用的術語。 –

回答

2

無論內存泄漏,這不是推薦的鑄造方式。所提供的示例使用C風格轉換,儘管它們可以工作,但很容易導致未定義的行爲(如果類型層次不匹配)。

通過baseptr=&der;上溯造型是好的,但更常見的通話將很簡單:

base* baseptr = new derived(); 

如果創建的對象是派生類這將始終工作。

向下轉換應該通過dynamic_cast進行,例如:

base* baseptr = new base(); 
derived* derptr = dynamic_cast<derived>(baseptr); // will fail, derptr == nullptr 

如果指針不能被鑄造成一個派生(真 - 延長關於基地)類,dynamic_cast將返回nullptr。你應該檢查一下。在上面的示例中,投射將失敗並且derptr == nullptr解析爲true

+1

dynamic_cast的問題是,基類需要至少有一個虛函數,而OP例子則不是這種情況。 –

+0

必須激活RTTI。請參閱您的編譯器文檔以瞭解如何使用。 – YSC

2

如果你垂頭喪氣,你必須要確保所投放對象的運行時類型真的是目標類型。當您將指針指向baseob以指向derived時,您與類型系統發生衝突,因爲現在指向derived的指針不指向derived