Chinaunix
标题:
函数参数为基类指针的引用,为何不能传子类的指针给它?
[打印本页]
作者:
csoapy
时间:
2012-04-01 13:53
标题:
函数参数为基类指针的引用,为何不能传子类的指针给它?
代码:
#include <list>
class ICommand{};
class CSession : public ICommand{};
void Test(ICommand * & pCommand){}
int main(int argc, char *argv[])
{
std::list<ICommand*> commands;
std::list<CSession*> sessions;
Test(*commands.begin());
Test(*sessions.begin());
return 0;
}
复制代码
Test(*sessions.begin())一行:error C2664: 'Test' : cannot convert parameter 1 from 'CSession *' to 'ICommand *&'
作者:
bruceteen
时间:
2012-04-01 14:08
很显然的
如果这是允许的……,还是用代码来说吧
struct base {};
struct foo : base {};
int main()
{
foo* p = new foo;
base*& pb = p;
pb = new base;
return 0;
}
复制代码
如果此语法能通过的话,此后(就是pb = p以后),p的静态类型为foo,但动态类型将变为base
所以你这个问题等同于为什么不能 foo* p = new base 一样
作者:
starwing83
时间:
2012-04-01 14:13
回复
2#
bruceteen
动态类型是根本不会变的啦。
根本原因是,B是D的基类,然而B*不是D*的基类,你可以试试:
foo *p = new foo();
base **pb = &p;
看看是啥结果。
作者:
csoapy
时间:
2012-04-01 15:11
本帖最后由 csoapy 于 2012-04-01 15:24 编辑
谢谢楼上两位,总算明白了原因。
就是D is a kind of B, but a pointer to D is not a kind of a pointer to B.
也就是,指针就是指针,无继承关系。不能说一种指针是另一种指针,即使它们指向的类是继承关系。
Test()的原意是,操作ICommand * & pCommand,然后再把pCommand值空。所以要传引用,或者二级指针,但是都通不过。一时还没想出来该怎么办,只想在Test()中delete 该指针,然后值空。作了如下修改,但仍旧通不过。还是cannot convert parameter 1 from 'ICommand *' to 'ICommand *&',也许是我还是没明白?
#include <list>
class ICommand{};
class CSession : public ICommand{};
void Test(ICommand * & pCommand){delete pCommand; pCommand = NULL;}
int main(int argc, char *argv[])
{
ICommand * pCommand = new ICommand();
CSession * pSession = new CSession();
std::list<ICommand*> commands; commands.push_back(pCommand);
std::list<CSession*> sessions; sessions.push_back(pSession);
Test(*commands.begin());
ICommand *p = dynamic_cast<ICommand*>(*sessions.begin());
Test(p);
sessions.push_back(new CSession());
Test(dynamic_cast<ICommand*>(*sessions.begin())); // cannot convert parameter 1 from 'ICommand *' to 'ICommand *&'
return 0;
}
复制代码
作者:
csoapy
时间:
2012-04-01 19:23
唉,在编译时刻要保证引用必须指向一个对象,Test(dynamic_cast<ICommand*>(*sessions.begin())); 要求使用引用,但sessions.begin()返回的是临时的、运行时的,编译器不知道该把引用指向哪,所以报错
作者:
x5miao
时间:
2012-04-01 19:58
本帖最后由 x5miao 于 2012-04-01 19:58 编辑
回复
5#
csoapy
这就如同使用变量可以绑定该变量的类型的引用,但却不允许引用的引用来绑定引用是一个道理。
欢迎光临 Chinaunix (http://bbs.chinaunix.net/)
Powered by Discuz! X3.2