基类指针指向继承类的子类,不能访问继承类重写的虚函数吗?

qq_41220807 2019-06-13 02:33:44
比如下面这样
#include <iostream>
using namespace std;

class A
{
public:
A()
:a(1)
{}
virtual void add()
{
cout << "A::add()" << endl;
}
int a;
};
class B : public A
{
public:
B()
:b(2)
{}
virtual void add()
{
cout << "B::add()" << endl;
}
virtual void FunB()
{
cout << "FunB()" << endl;
}
int b;
};

class C : public B
{
public:
C()
:c(4)
{}
virtual void add()
{
cout << "C::add()" << endl;
}
int c;
};

int main()
{
A* a = new C;
a->B::add();// error: 'B' is not a base of 'A'
return 0;
}
...全文
118 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_41220807 2019-06-14
  • 打赏
  • 举报
回复
引用 5 楼 真相重于对错 的回复:
说白了就是 父类的指针可以指向子类而 子类的指针不能指向父类 例如 class A{ public: int b; }; class B:public A{ public: int c; }; 如果子类的指针指向了父类那么它如何访问子类的变量 B* b1=new A; b1->c = 10;//b1其实指向了一个A对象,而这个对象根本不包括c字段,它如何访问?
好像明白了,谢谢
qq_41220807 2019-06-14
  • 打赏
  • 举报
回复
引用 4 楼 真相重于对错 的回复:
你的写法是错误 你可以写成 B* b = new C; b->A::add();//调用A的虚拟函数add 但是你不能用 a->B::add(); 因为 每一个类成员函数都有一个不显示出来的参数const typename* this; B::add 因此也有一个固定的不显示出来的参数const B* this; 而a->B::add它的this是一个 const A* 一个接受子类指针的参数,无法传给他一个父类的指针 再贴一段代码,可能你会理解 class A{}; class B:A{}; void test1(A*){} void test2(B*){} ... A* a = new B; test1(a) //合法 test2(a) 不合法;
我想的是,B不是A的子类吗,A*应该可以指向子类的虚函数啊
真相重于对错 2019-06-13
  • 打赏
  • 举报
回复
说白了就是 父类的指针可以指向子类而 子类的指针不能指向父类 例如 class A{ public: int b; }; class B:public A{ public: int c; }; 如果子类的指针指向了父类那么它如何访问子类的变量 B* b1=new A; b1->c = 10;//b1其实指向了一个A对象,而这个对象根本不包括c字段,它如何访问?
真相重于对错 2019-06-13
  • 打赏
  • 举报
回复
你的写法是错误 你可以写成 B* b = new C; b->A::add();//调用A的虚拟函数add 但是你不能用 a->B::add(); 因为 每一个类成员函数都有一个不显示出来的参数const typename* this; B::add 因此也有一个固定的不显示出来的参数const B* this; 而a->B::add它的this是一个 const A* 一个接受子类指针的参数,无法传给他一个父类的指针 再贴一段代码,可能你会理解 class A{}; class B:A{}; void test1(A*){} void test2(B*){} ... A* a = new B; test1(a) //合法 test2(a) 不合法;
Hit不死的小强 2019-06-13
  • 打赏
  • 举报
回复
引用 2 楼 qq_41220807 的回复:
[quote=引用 1 楼 至尊宝、 的回复:]
可以访问,而且你如果写成虚函数,那么基类指针指向派生类就只能访问派生类重写的函数。
你这个主函数里调用的时候写错了,应该这么写:
int main()
{
A* a = new C;
a->add();// error: 'B' is not a base of 'A'
return 0;
}

满意请结帖给分。

这样访问的是继承类的继承类的add函数了,希望访问的是中间那个继承类的B::add()[/quote]那个是访问不了的,因为你在c中重写了函数,而虚函数有一张虚函数表,当你重写了函数的时候,他就会在表中把基类的原函数覆盖掉,你无法访问到它的上一层的虚函数的
qq_41220807 2019-06-13
  • 打赏
  • 举报
回复
引用 1 楼 至尊宝、 的回复:
可以访问,而且你如果写成虚函数,那么基类指针指向派生类就只能访问派生类重写的函数。 你这个主函数里调用的时候写错了,应该这么写:
int main()
{
	A* a = new C;
	a->add();// error: 'B' is not a base of 'A'
	return 0;
}
满意请结帖给分。
这样访问的是继承类的继承类的add函数了,希望访问的是中间那个继承类的B::add()
Hit不死的小强 2019-06-13
  • 打赏
  • 举报
回复
可以访问,而且你如果写成虚函数,那么基类指针指向派生类就只能访问派生类重写的函数。
你这个主函数里调用的时候写错了,应该这么写:
int main()
{
A* a = new C;
a->add();// error: 'B' is not a base of 'A'
return 0;
}

满意请结帖给分。

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧