指针和左移位运算符的引用

时间:2011-09-01 07:49:26

标签: c++ pointers casting operator-overloading pass-by-reference

我重新定义了<<运算符,我希望它引用指针。

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);

有什么想法吗?

4 个答案:

答案 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_pointerbase_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...