什么使向上转型和向下转型非法
What make upcasting and downcasting illegal
讲课的时候有同学说这种上扬下扬没有逻辑,是违法的。一些老师如何感到困惑并同意并说他会审查并再次讲课,但我不知道这段代码有什么问题,是否存在这种情况是非法的。
#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;
}
如果你向下转型,你必须确保被转型对象的运行时类型确实是目标类型。当您将指向 baseob
的指针转换为指向 derived
的指针时,您对类型系统犯规了,因为现在您有一个指向 derived
的指针,但它并不指向 derived
].
无论内存泄漏如何,这都不是推荐的转换方式。提供的示例使用 C 样式转换,尽管它们有效,但很容易导致未定义的行为(如果类型层次结构不匹配)。
通过 baseptr=&der;
向上转换很好,尽管更常见的调用是简单地:
base* baseptr = new derived();
如果创建的对象是派生的 class,这将始终有效。
应通过 dynamic_cast
执行向下转换,例如:
base* baseptr = new base();
derived* derptr = dynamic_cast<derived>(baseptr); // will fail, derptr == nullptr
如果不能将指针转换为派生(实际上是关于基的扩展)class,dynamic_cast
将 return 为 nullptr。你应该检查一下。在上面的示例中,转换将失败并且 derptr == nullptr
解析为 true
.
讲课的时候有同学说这种上扬下扬没有逻辑,是违法的。一些老师如何感到困惑并同意并说他会审查并再次讲课,但我不知道这段代码有什么问题,是否存在这种情况是非法的。
#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;
}
如果你向下转型,你必须确保被转型对象的运行时类型确实是目标类型。当您将指向 baseob
的指针转换为指向 derived
的指针时,您对类型系统犯规了,因为现在您有一个指向 derived
的指针,但它并不指向 derived
].
无论内存泄漏如何,这都不是推荐的转换方式。提供的示例使用 C 样式转换,尽管它们有效,但很容易导致未定义的行为(如果类型层次结构不匹配)。
通过 baseptr=&der;
向上转换很好,尽管更常见的调用是简单地:
base* baseptr = new derived();
如果创建的对象是派生的 class,这将始终有效。
应通过 dynamic_cast
执行向下转换,例如:
base* baseptr = new base();
derived* derptr = dynamic_cast<derived>(baseptr); // will fail, derptr == nullptr
如果不能将指针转换为派生(实际上是关于基的扩展)class,dynamic_cast
将 return 为 nullptr。你应该检查一下。在上面的示例中,转换将失败并且 derptr == nullptr
解析为 true
.