运算符 float*() 有啥作用?

Posted

技术标签:

【中文标题】运算符 float*() 有啥作用?【英文标题】:What does operator float*() do?运算符 float*() 有什么作用? 【发布时间】:2014-08-07 07:36:06 【问题描述】:

我一直在查看源代码,试图了解有关 C++ 的更多信息,但遇到了一些看起来令人困惑的代码。我无法通过玩弄它来弄清楚它的用途。

请谁能解释一下操作符 float *() 的作用以及它是如何使用的?

类向量 民众: 浮动 x,y,z; Vector() : x(0), y(0), z(0) Vector( float x, float y, float z ) : x(x), y(y), z(z) operator float*() return &x; operator const float *() return &x;

我已经搜索过 ***,它看起来像是一个转换运算符,但我仍然不确定它的实际作用以及它为什么有用。

亲切的问候,

【问题讨论】:

到目前为止,没有一个答案可以解释为什么它转换为float* 而不是float。非常量可能是故意破坏封装的愿望,但为什么有人会写const float * 转换? ---> 啊哈,刚刚看到马特关于假设 x,y,z 在内存中是连续的这一点的评论。好的,可疑的设计,但我现在明白了:-) @Darren 我不会试图解释它,因为我不能。这简直是​​个坏主意。我怀疑原作者想为向量公开一个类似数组的接口,但这是一个坏主意,因为我的答案(以及更多)下面的 cmets 中提到的原因。 【参考方案1】:

operator <em>type_name</em> 声明了一个隐式转换 运算符。换句话说,当您尝试(隐式)将您的类型的对象转换为 float* 时调用此函数——例如在赋值中:

Vector x(1, 2, 3);
float* f = x;
assert(*f == 1);

不用说,这种特殊的转换非常糟糕,因为它的效果非常不直观,并且很容易导致无法找到错误。隐式转换通常应该小心处理,因为它们隐藏了潜在的混淆语义。但是它们可以很好地与应该可以互换使用的类型一起使用,并且转换不会造成伤害。

例如,考虑您编写自己的integercomplex 类的情况。从integercomplex 的转换是无害的,因为每个整数都是复数(但不是反之亦然)。所以隐式转换 integercomplex 是安全的。

【讨论】:

支持它很糟糕。 更安全的选择是:float &operator[]( int n) return (&x)[n]; @MattMcNabb 假设这确实是类的全部定义(或者至少它没有虚拟成员和基类),那么它们实际上保证是连续的并且按照它们被声明的顺序,因为它是一个标准布局结构。 @Matt McNabb 保证数据成员的顺序。 @Angew 和 Vlad - 你说得对;虽然这个类是非 POD,但它仍然是由[class]#7 指定的 standard-layout【参考方案2】:

正如所说的,它是一个转换运算符,将Vector 类型的对象转换为float * 类型的对象。这个转换运算符可以被隐式调用,因为它没有函数说明符explicit

我认为引入此运算符的想法是将数据成员 x、y、z 作为浮点数组访问。在这种情况下,您可以将一些标准算法应用于类的对象,将其转换为浮点数组。

考虑到第二个重载的运算符函数应该有限定符 const。

考虑下面的代码

#include <iostream>
#include <algorithm>


class Vector

public:
    float x,y,z;



    Vector() : x(0), y(0), z(0)
    

    Vector( float x, float y, float z ) : x(x), y(y), z(z)
    

    operator float*()
        return &x;
    

    operator const float *() const 
        return &x;
    
;

int main() 

    Vector v( 1, 3, 2 );
    auto max = std::max_element( v + 0, v + 3 );
    std::cout << *max << std::endl;

    return 0;

输出为 3。

考虑到根据 C++ 标准

具有相同访问权限的(非联合)类的 13 个非静态数据成员 分配控制权(第 11 条)以便 后来的成员拥有更高的 类对象中的地址

所以定义了类的数据成员的顺序。

【讨论】:

【参考方案3】:

这是一个转换运算符,允许将类与需要 float* 的 API 一起使用。您有两个不同的版本,因为一个会将类转换为 const float*,而另一个将转换为非 const。但是,非常量转换运算符会破坏您的类的封装。

有用性:正如我所提到的,当您想要使用需要特定类型的库时,它会非常方便。当两种类型之间存在自然转换时,它也很有用。

【讨论】:

@Angew 感谢 pointer :) 显然,当我指出封装损坏时,我知道这一点,但我的回答不清楚。我已经更新了。

以上是关于运算符 float*() 有啥作用?的主要内容,如果未能解决你的问题,请参考以下文章

一元问号 (?) 运算符有啥作用?

冒号 (:) 运算符有啥作用?

运算符 delete[] 有啥作用? [复制]

插入符号 (^) 运算符有啥作用?

^ (XOR) 运算符有啥作用? [复制]

双 * (splat) 运算符有啥作用