C++中。父类指针指向子类与子类指针指向父类有什么区别?
时间: 2024-03-03 20:44:32 浏览: 144
父类指针指向子类对象和子类指针指向父类对象在C++中有以下区别:
1. 父类指针指向子类对象:
- 在继承关系下,父类的指针可以直接指向子类对象,无需进行强制类型转换。
- 通过父类指针调用的成员函数将会调用子类中的同名函数(如果存在),实现了多态性。
- 父类指针无法访问子类中新增的成员函数和成员变量。
2. 子类指针指向父类对象:
- 在继承关系下,子类的指针不能直接指向父类对象,会导致编译错误。
- 子类指针只能访问父类中的成员函数和成员变量,无法访问子类中新增的成员函数和成员变量。
- 如果通过子类指针调用的成员函数在父类中被重写,将会调用父类中的同名函数,而不是子类中的函数。
总结起来,父类指针指向子类对象可以实现多态性,而子类指针指向父类对象则无法实现多态性,并且存在类型不匹配的问题。
相关问题
什么时候会用到父类指针指向子类指针呢?
一般来说,父类指针指向子类对象的情况是常见的,特别是在多态性编程中,当您想要保持接口的一致性并且允许不同类型的对象共享同一份代码时。然而,直接让子类指针指向父类对象通常是不推荐的,因为这可能会导致运行时错误[^1]。
例如,在C++中,如果有一个基类`Person`和派生类`student`,您可能会这样设计:
```cpp
class Person {
public:
// 基类的方法
virtual void displayInfo() {
std::cout << "This is a person." << std::endl;
}
};
class student : public Person {
private:
int m_score;
public:
// 派生类的方法
void displayScore() {
std::cout << "Score: " << m_score << std::endl;
}
// 虚函数实现
virtual void displayInfo() override {
Person::displayInfo();
displayScore();
}
};
int main() {
Person* p = new student(); // 父类指针指向子类对象
p->displayInfo(); // 可以调用派生类的displayInfo()
delete p; // 正确删除,因为p实际上是指向子类的
// 如果尝试反过来,如student* s = dynamic_cast<student*>(p); 就是不安全的
// 这里就不演示,因为这通常会导致编译错误或运行时异常
}
```
在这种情况下,通过父类指针操作子类对象,可以避免直接暴露派生类的细节,保持代码的灵活性。但若要直接修改子类特性,应该使用子类指针[^2]。
虚函数 父类指针指向子类
虚函数是一种特殊类型的成员函数,在C++中,当我们在父类的指针或引用上声明它为虚函数时,即使该指针实际上指向的是子类的对象,调用这个函数时会根据实际对象的类型动态地调用子类的实现。这种机制实现了动态绑定,也称为晚期绑定或运行时多态。
举个例子:
```cpp
class Base {
public:
virtual void display() { // 虚函数声明
cout << "Base class" << endl;
}
};
class Derived : public Base {
public:
void display() override { // 子类重写虚函数
cout << "Derived class" << endl;
}
};
int main() {
Base* basePtr = new Derived(); // 父类指针指向子类对象
basePtr->display(); // 运行时调用Derived的display()
delete basePtr; // 删除对象
return 0;
}
```
在这个例子中,虽然`basePtr`是一个`Base`类型的指针,但我们通过它调用`display()`时,实际上是调用了`Derived`类的版本,这就是虚函数在父类指针下工作的原理。
阅读全文