通过基类指针取消引用
De-referencing through base class pointer
最近关于SO的一个问题让我思考了以下问题
考虑以下代码:
class Base{
public:
void print() { cout<<"In Base"<<endl;}
};
class Derived: public Base{
public:
void print() { cout<<"In Derived"<<endl;}
};
int main(void)
{
Base *bp;
Derived ob;
bp = &ob;
(*bp).print(); // prints: In Base
ob.print(); // print: In Derived
return 0;
}
为什么(*bp),print()
的行为与ob.print()
不同。
我认为(*bp)应该返回对象ob
,因为bp
被引用到对象ob
,并且当我们使用*
运算符取消引用时,我们得到该地址的值,并且ob
对象存储在bp
中存在的地址。因此,第一个函数调用应该与发送函数调用相同。
请澄清概念。
你所做的被称为"方法隐藏",是一种代码气味,一种坏习惯,一种不应该做的事情。
您应该在基类中将打印方法定义为virtual
。(也不要忘记Base
类中的virtual
析构函数。)
class Base{
public:
virtual void print() { cout<<"In Base"<<endl;}
virtual ~Base(){}
};
class Derived: public Base{
public:
void print() { cout<<"In Derived"<<endl;}
};
您是否错过了声明函数print()
virtual
?;)
class Base{
public:
virtual void print() { cout<<"In Base"<<endl;}
};
决策始终基于指针类型而非指针内容。前者的绑定被称为Early Binding
,后者是Late Binding
。
如果我们重新定义前面有virtual
关键字的方法print(),结果将是必需的。
class Base
{
public:
virtual void print()
{
cout<<"In Base"<<endl;
}
};
class Derived: public Base
{
public:
void print()
{
cout<<"In Derived"<<endl;
}
};
当您使用指向基类的指针或引用引用派生类对象时,可以为该对象调用虚拟函数,并执行派生类的函数版本。虚拟函数确保为对象调用正确的函数,而不管用于调用函数的表达式是什么。
当使用指针或引用调用函数时,以下规则适用:
- 对虚拟函数的调用根据底层为其调用的对象的类型
- 对非虚拟函数的调用根据指针或引用
您可以浏览虚拟表和虚拟函数的概念以了解更多详细信息
编译器使用静态类型的变量。变量bp具有静态类型Base*,因此编译器会检查Base的类定义中是否存在这样的函数并调用它。您想要达到的效果可以使用虚拟函数来实现。在这种情况下,编译器使用指向虚拟函数的指针表来调用函数。在这种情况下,由于bp具有动态类型Derived*,因此表将包含指向Derived类中定义的虚拟函数的指针。您所需要做的就是将函数说明符virtual添加到Base类中的函数定义中
class Base{
public:
virtual void print() { cout<<"In Base"<<endl;}
virtual ~Base() = default};
Base
可能有很多派生类。在(*bp).print()
的时刻,您不知道它们中的哪一个(如果有的话)是底层对象的真实类。所以编译器所能做的就是调用Base::print
。
但是,如果您包含了一些关于实际类(vtable
)的信息,那么就可以按照您想要的方式进行操作(按照其他人的建议,使用virtual
函数)。
- C++取消引用指针.为什么会发生变化
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- 取消引用运算符不能重载
- 在他自己的方法中,有可能将一个对象取消引用到另一个对象吗
- C++ 关于指针取消引用的技术问题
- 没有取消引用/解包对象的标准方法?
- 列表 iter 不取消引用 使用列表进行插入排序
- 在这个函数中是有缺陷的,因为取消引用 null 是无效的,所以我想更改代码
- 取消引用结束指针到数组类型的一个
- 取消引用向量时出现问题
- 取消引用指向整数的指针时获得不同的结果
- C++:取消引用十六进制值,有点语法问题
- C/C++ 取消引用错误:在空检查之前取消引用
- 取消引用后C++空测试
- 立即取消引用unique_ptr
- 如何在不使用临时变量的情况下取消引用返回指针的函数的返回值?
- 取消引用 void 指针以将值分配给结构
- boost_multi_index迭代器取消引用给出常量
- 矢量迭代器不能与 std::shared_ptr<> 取消引用
- C++我们可以取消引用此指针吗?如果是这样,那么如何,如果不是,那为什么?