协变返回类型的问题 [英] Problem with covariant return types

查看:66
本文介绍了协变返回类型的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我原本以为这是编译器错误,但似乎标准

禁止下面的代码。有没有人对如何编码

周围有什么好主意?


A级;

B级;

class X;

class Y;


class X

{

public:


虚拟A * g()const;

};


类Y:public X

{

public:


虚拟B * g()const;

};


[此时编译器发出错误信号(非协变返回类型)

因为它不知道B来自A]


A级

{

公开:


虚拟X * f()const ;

};

B级:公共A

{

public:

虚拟Y * f()const;

};


谢谢,


Rob 。

解决方案

* Rob.::blockquote class =post_quotes>
我原本认为这是一个编译器错误,但似乎是小号标准
禁止下面的代码。有没有人对它周围的代码有什么好的想法?

A类;
B类;
X类;
Y类;

X类
公开:

虚拟A * g()const;
};

Y级:公共X
公开:

虚拟B * g()const;
};

[编译器信号此时出现错误(非协变返回类型)
因为它不知道B是从A开始的。

A级
{
公众:

虚拟X * f()const;
};

B级:公共A
{
公开:
虚拟Y * f()const;
};



关闭袖口:

A级;

B级;

等级X;

等级Y;


等级X

{

public:

virtual A * g()const;

A * gA()const;

};


Y类:公共X

{

公开:

虚拟A * g()const;

B * gB();

};

A级

{

public:

虚拟X * f()const;

X * fX()const;

};

B级:公共A

{

公开:

虚拟X * f()const;

Y * fY();

};

A * X :: gA()const {return g(); }

B * Y :: gB()const {return static_cast< B *>(g()); }

X * A :: fX()const {return f(); }

Y * B :: fY()const {return static_cast< Y *>(f()); }


-

答:因为它弄乱了人们通常阅读文字的顺序。

问:为什么是这是一件坏事吗?

答:热门发布。

问:usenet和电子邮件中最烦人的是什么?


2004年6月26日星期六09:57:41 +0300,Rob。 < RO **** @ xxx.fi>写道:

我原本认为这是一个编译器错误,但似乎标准
禁止下面的代码。有没有人对如何围绕它进行编码有什么好的想法?



[snip]


它是什么编译器?例如,MSVC 6.0尚未支持

协变返回类型IIRC。然而,它在版本7.x中支持它们。


-

Bob Hairgrove
没有********** @ Home.com


" Alf P. Steinbach <人*** @ start.no>在消息中写道

class X
class Y:public X
class A
{
public:
virtual X * f()const;
X * fX()const;
};

B级:公开A
{
公开:
virtual X * f()const;
Y * fY();
};

A * X :: gA()const {return g(); } B / Y :: gB()const {return static_cast< B *>(g()); X * A :: fX()const {return f(); } * / / Y * B :: fY()const {return static_cast< Y *>(f()); }




这是个好主意。可以将它用于用户类型。假设基类

返回shared_ptr< X>并且派生类返回一个shared_ptr< Y>,我们知道它是协变的,但是编译器没有。


只有我自己在过去完成的是将fX()和fY()重命名为f()。所以

我的班级看起来像这样:


A级

{

私人/受保护:

虚拟X * dof()const;

public:

counting_ptr< X> f()const {return dof(); }

};


B级:公共A

{

私人/受保护:

虚拟X * dof()const;

public:

counting_ptr< Y> f()const {return static_cast< Y *>(dof()); }

};


但等一下。我违反了你不应该超越

非虚函数的指导原则。一般来说,这是一个很好的规则,我们应该尊重
。因为当我们从指向基类的指针调用函数时,系统应该调用派生类函数 - 而最流行的

例子是虚拟析构函数。


但在上面的类设计中,我们调用派生类函数,

即dof()。这只是A :: f()将返回类型强制转换为A类知道的
,即X *或counting_ptr< X>。大概是A.h

包括X.h或者前向声明类X.而B :: f()也会调用派生的

类函数,即dof()。假设B :: dof()返回一个对象

,其为Y或更高,作为X *投射,B :: f()完全可以投这个

到count_ptr< Y>。毕竟这是同一个对象。


因此,当我们按照上述习语时,打破你不应该的

指南似乎完全可以覆盖非虚函数。任何

的想法?


I originally thought this was a compiler error but it seems the standard
prohibits the code below. Has anyone got any good ideas about how to code
around it?

class A;
class B;
class X;
class Y;

class X
{
public:

virtual A* g () const;
};

class Y : public X
{
public:

virtual B* g () const;
};

[The compiler signals an error (non-covariant return types) at this point
because it doesn''t know that B is derrived from A]

class A
{
public:

virtual X* f () const;
};
class B : public A
{
public:

virtual Y* f () const;
};

Thanks,

Rob.

解决方案

* Rob.:


I originally thought this was a compiler error but it seems the standard
prohibits the code below. Has anyone got any good ideas about how to code
around it?

class A;
class B;
class X;
class Y;

class X
{
public:

virtual A* g () const;
};

class Y : public X
{
public:

virtual B* g () const;
};

[The compiler signals an error (non-covariant return types) at this point
because it doesn''t know that B is derrived from A]

class A
{
public:

virtual X* f () const;
};
class B : public A
{
public:

virtual Y* f () const;
};


Off the cuff:
class A;
class B;
class X;
class Y;

class X
{
public:
virtual A* g() const;
A* gA() const;
};

class Y : public X
{
public:
virtual A* g() const;
B* gB();
};
class A
{
public:
virtual X* f() const;
X* fX() const;
};
class B : public A
{
public:
virtual X* f() const;
Y* fY();
};
A* X::gA() const { return g(); }
B* Y::gB() const { return static_cast<B*>( g() ); }
X* A::fX() const { return f(); }
Y* B::fY() const { return static_cast<Y*>( f() ); }

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?


On Sat, 26 Jun 2004 09:57:41 +0300, "Rob." <ro****@xxx.fi> wrote:

I originally thought this was a compiler error but it seems the standard
prohibits the code below. Has anyone got any good ideas about how to code
around it?


[snip]

What compiler is it? MSVC 6.0, for example, did not yet support
covariant return types IIRC. It supports them in version 7.x, however.

--
Bob Hairgrove
No**********@Home.com


"Alf P. Steinbach" <al***@start.no> wrote in message

class X
class Y : public X class A
{
public:
virtual X* f() const;
X* fX() const;
};
class B : public A
{
public:
virtual X* f() const;
Y* fY();
};
A* X::gA() const { return g(); }
B* Y::gB() const { return static_cast<B*>( g() ); }
X* A::fX() const { return f(); }
Y* B::fY() const { return static_cast<Y*>( f() ); }



This is a great idea. One can use it for user types. Say the base class
returns a shared_ptr<X> and the derived class returns a shared_ptr<Y>, which
we know is covariant but the compiler doesn''t.

Only thing I''ve done in the past is to to rename fX() and fY() to f(). So
my class looks like this:

class A
{
private/protected:
virtual X* dof() const;
public:
counted_ptr<X> f() const { return dof(); }
};

class B : public A
{
private/protected:
virtual X* dof() const;
public:
counted_ptr<Y> f() const { return static_cast<Y*>(dof()); }
};

But wait a sec. I''ve violated the guideline that you ought not to override
a non-virtual function. In general, this is a fine rule that we ought to
respect. Because when we call a function from a pointer to the base class,
the system ought to call the derived class function -- and the most popular
example of this is the virtual destructor.

But in the above class design, we are calling the derived class function,
namely dof(). It''s just that A::f() casts the return type to something
class A knows about, namely an X* or counted_ptr<X>. Presumably A.h
includes X.h or forward declares class X. And B::f() also calls the derived
class function, namely dof() again. Assuming B::dof() returns an object
that is Y or higher cast as an X*, it''s perfectly OK for B::f() to cast this
to a counted_ptr<Y>. It''s the same object after all.

So when we follow the above idiom, it seems perfectly OK to break the
guideline that you ought not to override a non-virtual function. Any
thoughts?


这篇关于协变返回类型的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆