我重新定义了<<运算符,我希望它引用指针。
class foo
{
foo();
virtual ~foo();
void operator << (BaseService*& iRight);
}
在代码中的某个地方,有一个foo实例,以及一个BaseService类专门化的服务:
Service* service_pointer = new Service();
foo_instance << service_pointer;
但是我收到了这个错误: 错误:'foo_instance&lt;&lt;'中的'operator&lt;&lt;'不匹配service_pointer” 注意:候选人是:void foo :: operator&lt;&lt;(BaseService *&amp;)
如果我将service_pointer dynamic_cast添加到BaseService
,则没有任何变化Service* service_pointer = new Service();
foo_instance << dynamic_cast<BaseService*>(service_pointer);
有什么想法吗?
答案 0 :(得分:3)
第一个版本不起作用,因为您无法传递对指向子类型的指针的引用,这是正确的:如果operator<<
的实现使指针指向实例MyService
,该怎么办? (这是BaseService
的子类,但不是Service
的子类)?显然,Service*
指向MyService
是违法的。因此不允许传入Service*
。
不允许使用第二个版本,因为dynamic_cast
不返回l值,因此您不能将其作为非const引用传递。
您唯一能做的就是定义另一个BaseService*
类型的变量,并将其作为参数传递给<<
。如果<<
然后重新指定指针,则该更改仅对新创建的变量可见,不会影响ServicePointer
。
如果说(并且不知道你的用例)我必须建议你让operator<<
对任何东西进行非const引用,因为它的右操作数会让我感觉不好。您通常不希望<<
修改它的右操作数。
答案 1 :(得分:1)
仅因为Service *
类型可转换为BaseService *
类型并不意味着Service *&
类型可转换为BaseService *&
类型。事实并非如此。这就是你的第一个调用无法编译的原因。
尝试使用dynamic_cast
(或任何其他非黑客演员)无济于事。这种演员的结果不是左值。而且你不能将非const引用绑定到不是左值的东西。这就是你的第二次调用无法编译的原因。
如果您真的希望您的运营商专门接受BaseService *&
,那么您只能执行Service *
到{em>左值的手动预转换{{1} (即显式指针对象),然后使用该左值
BaseService *
如果您将运算符更改为
,则会对您对运算符Service* service_pointer = new Service();
BaseService* base_service_pointer = service_pointer;
foo_instance << base_service_pointer;
的调用进行编译
<<
但是否能否做到取决于你的意图。你为什么试图通过引用传递指针?
答案 2 :(得分:0)
您必须实际定义BaseService
指针变量。
Service* service_pointer = new Service();
BaseService* base_service_pointer = dynamic_cast<BaseService*>(service_pointer);
foo_instance << base_service_pointer;
如果你想引用指针,它不能是一个右值。
另请注意,此处不需要dynamic_cast<>
。一个static_cast<>
就可以了。更妙的是,使用从service_pointer
到base_service_pointer
的简单作业!
答案 3 :(得分:0)
这不可能有效,因为引用是非const的,所以你可以在foo :: operator&lt;&lt;中更改指针值。请考虑以下示例:
class Service1 : BaseService
{
};
class Service2 : BaseService
{
};
void foo::operator << (BaseService*& iRight)
{
// ok, iRight is a reference to BaseService*
// so we can assign Service2* to it, can't we?
iRight = new Service2();
}
Service1* service_pointer = new Service1();
foo_instance << service_pointer; // oops...