关于虚函数

当您使用基类指针`p`来调用成员函数时,对于非虚函数,编译器会根据指针的类型(在这里是`A*`)来决定调用哪个函数。对于虚函数,编译器会根据对象的实际类型(在这里是`B`对象)来决定调用哪个函数。

在这段代码中:

```cpp
A *p = &a;
p->foo();  // 输出1,因为p是A类型的指针,所以调用A::foo
p->fun();  // 输出2,因为fun是虚函数,p指向a,所以调用A::fun
p = &b;
p->foo();  // 输出1,即使p现在指向B对象b,foo是非虚函数,所以依然调用A::foo
p->fun();  // 输出4,fun是虚函数,p指向B对象b,所以调用B::fun,体现多态
```

您提到的这一行:

```cpp
p->foo();  // 取决于指针类型,输出1
```

实际上,输出是`1`,这是因为`foo`函数在`A`类中没有被声明为虚函数,所以编译器会根据指针的类型(`A*`)来解析函数调用。即使`p`指针后来被赋值为指向`B`对象,调用`foo`函数时仍然会调用`A::foo`,因为`foo`不是虚函数,编译器不会考虑对象的实际类型。

如果您希望`foo`函数在派生类`B`中被覆盖,您需要在基类`A`中将其声明为虚函数:

```cpp
class A  
{  
public:  
    virtual void foo()  // 声明为虚函数
    {  
        printf("1\n");  
    }  
    virtual void fun()  
    {  
        printf("2\n");  
    }  
};
```

在这种情况下,当`p`指向`B`对象时,调用`foo`函数将会输出`3`,因为`B::foo`现在是`A::foo`的覆盖版本,且`foo`是虚函数,所以编译器会根据对象的实际类型解析函数调用。

注意使用指针时,是根据 指针的类型(`A*`)来解析函数调用。即使`p`指针后来被赋值为指向`B`对象,调用`foo`函数时仍然会调用`A::foo`,因为`foo`不是虚函数,编译器不会考虑对象的实际类型。

而不使用指针时比如以下这种情况:跟指针是不同的 !!:直接创建对象并调用函数。

class Base {
public:
    void func() {
        std::cout << "Base class func" << std::endl;
    }
};

class Derived : public Base {
public:
    void func() { // 这个函数屏蔽了基类中的func
        std::cout << "Derived class func" << std::endl;
    }
};

int main() {
    Derived d;
    d.func(); // 调用的将是Derived类中的func,输出: Derived class func
    // Base类的func被屏蔽,无法通过Derived对象d直接调用
    return 0;
}

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值