当前位置:  开发笔记 > 编程语言 > 正文

返回铸造参考是否安全?

如何解决《返回铸造参考是否安全?》经验,为你挑选了2个好方法。

我们Point是一个类,其实例可以明确地浇铸为wxPoint:

class Point{
private:
    int x;
    int y;
public:
    explicit operator wxPoint() const
    {
        return wxPoint(x, y);
    }

    // More stuff
}

我有一个函数返回对类型对象的引用Point.这样一个函数的标题是:

const Point& GetPoint();

我的问题:定义以下Foo功能是否安全?

const wxPoint& Foo() const{
    return (wxPoint&) GetPoint();
}

首先我实现Fooreturn (wxPoint) GetPoint();,但是创建了一个新的(本地)对象,因此触发了一个有用的警告.此处显示的代码在没有警告的情况下编译.

我在这种类型的转换中找到的所有信息都是指继承的类,但这不是这种情况.

在以这种方式投射参考时究竟会发生什么的解释将非常感激.



1> MRB..:

实际上你的转换操作符从不被调用.您正在返回对point实例的引用GetPoint.后来你使用了一个C风格的演员,在你的情况下将相当于一个reinterpret_cast<>(见这里).您正在将引用Point转换为引用wxPoint,并且这两个类型是完全不相关的类型.另一方面,对返回引用的任何操作都是未定义的行为.

我的建议是始终使用C++强制转换运算符.他们有好处:

编译器检查C++样式转换.

可以轻松搜索C++样式转换.

C++样式转换表达了程序员的意图.


@ PeterA.Schneider将调用转换运算符来构造一个`wxPoint`临时,但是会尝试将`wxPoint&`绑定到那个不正确的临时表.问题是函数的返回类型:如果没有任何内容可以绑定引用,则无法返回引用.
C++演员的另一个优点是它们看起来很难看.演员应该是丑陋的,因为虽然他们经常有用,但他们总是值得进行额外的审查.
见[here](http://eel.is/c++draft/expr.cast#4).并注意中段:*"可以使用显式类型转换的强制转换表示法执行.同样的语义限制和行为适用,但在以下情况下执行static_cast时,即使基类是有效的,转换也是有效的.人迹罕至"*
对.这不是标准的问题,GCC太有帮助了.考虑[这个例子](http://coliru.stacked-crooked.com/a/e5670efedbd98f82).clang的警告表明发生了什么.您需要使用static_cast正确调整指针,但由于基础不可访问,因此无法使用.只有C风格的演员才能正确完成工作并且没有任何警告.
@StoryTeller哇.对我来说似乎是一个公理,一个C风格的演员除了C++演员之外没有做任何其他事情,按升序排列,直到一个成功.

2> Jonathan Wak..:

其他答案已经解释,铸造Point&wxPoint&简单地在于编译器,告诉它引用绑定到的对象是一个wxPoint对象,这是不正确的.如果尝试wxPoint通过该引用访问对象,则程序将具有未定义的行为,因为它未绑定到wxPoint对象.有时候当你骗到编译器时,它不能给你警告,只是要相信你没有做一些疯狂的事情.

修复是停止尝试返回对不存在的对象的引用:

wxPoint Foo() const {
    return GetPoint();
}

这将使用您的转换运算符构造一个wxPoint并按值返回,这是可以的.当没有任何东西可以绑定引用时,尝试通过引用返回是不行的.

推荐阅读
放ch养奶牛
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有