我对上传有疑问。 考虑有两个类,Class Parent和Class child。孩子继承了父母。
问题:
如果我为父项创建对象指针,并指定了子对象引用。我遵守了。输出是“对象切片”。无法访问子类特定组件
class Parent
{
public:
int i;
void school()
{
std::cout<<"Parent Class::School()"<<std::endl;
}
// virtual goToPlay()
// {
// std::cout<<"Parent Class::goToPlay()"<<std::endl;
// }
};
class Child:public Parent
{
public:
int j;
void goToPlay()
{
std::cout<<"Child Class::goToPlay()"<<std::endl;
}
};
int main()
{
Parent *mParent;
Child mChild;
mParent = &mChild;
mParent->school();
mParent->goToPlay(); //Error
无法访问goToPlay()API。如果我在父类中创建goToPlay()的虚函数,则可以访问它。任何人都可以说出原因吗?
答案 0 :(得分:1)
由于您的指针类型为Parent
,因此只能访问Parent的api,因为这是您告诉编译器的内容。 (即此指针指向Parent
个对象)。
在您的情况下,virtual
方法将调用正确的实现。 (这称为后期绑定,它在运行时通过实例中的隐藏表完成,以找到方法实现的正确地址,在您的情况下是Child
实现,因为mParent
指向{ {1}}实例)
答案 1 :(得分:1)
您明确声明Parent * mParent
,因此您的对象被视为Parent
的实例。在许多用例中,这正是您想要的 - 您提供了一个适当的界面来执行某些操作,具体使用的实现与最终用户无关:
class employee
{
public:
virtual double get_salary_in_usd() const = 0;
virtual ~employee() {}
};
class software_developer : public employee
{
public:
double get_salary_in_usd() const { return 100000.; /* i wish */ }
void be_awesome() {}
~software_developer() {}
};
void print_salary(std::shared_ptr<employee> const & emp)
{
std::cout << "This employee earns $" << emp->get_salary_in_usd()
<< " a month." << '\n';
}
但是,在某些情况下,您需要在运行时告诉您指针是否是基类的某个子节点。这是dynamic_cast
的用途:
software_developer me;
employee * me_generalized = &me;
software_developer * me_again = dynamic_cast<software_developer *>(
me_generalized);
if(me_again != nullptr)
{
me_again->be_awesome();
}
请注意,如果指针无法转换,dynamic_cast
可以返回nullptr
。另请注意,RTTI会在运行时发生这种情况,并会降低应用程序的速度。尽可能避免使用它。
答案 2 :(得分:1)
为了通过指向Child::goToPlay()
的指针使用Parent
,Parent
必须声明自己的函数goToPlay()
,并且必须标记此函数virtual
。然后,您的Child
课程将覆盖该职能。
然后,当您在goToPlay()
指针上调用Parent
时,会神奇地调用Child
函数。
但是,你不能只为Parent
中不存在的任意函数执行此操作。