简体   繁体   English

C++ 重载赋值运算符

[英]C++ overload assignment operator

I'm currently struggling with the assignment operator.我目前正在努力使用赋值运算符。 I keep missing something.我总是想念一些东西。 Could you help me out here?你能帮帮我吗?

Check it out here https://godbolt.org/z/rfvTqcjoT在这里查看https://godbolt.org/z/rfvTqcjoT

class SpecialFloat
{
    public:
    explicit SpecialFloat(const float f);

    SpecialFloat& operator=(const float f);
    private:
    float m_float;
};


SpecialFloat::SpecialFloat(const float f):
m_float(f)
{

}


SpecialFloat& SpecialFloat::operator=(const float f)
{
    m_float = f;
}

int main()
{
    SpecialFloat f = 1.0f;
}

why is my operator overloading not working?为什么我的运算符重载不起作用?

<source>(27): error C2440: 'initializing': cannot convert from 'float' to 'SpecialFloat'
<source>(27): note: Constructor for class 'SpecialFloat' is declared 'explicit'

or can the assignment operator not take custom types?或者赋值运算符不能采用自定义类型?

The line SpecialFloat f = 1.0f;SpecialFloat f = 1.0f; cannot perform assignment from 1.0f to f because f doesn't exist yet.无法执行从1.0ff的赋值,因为f还不存在。 We are just creating it.我们只是在创造它。

It would do if you had written SpecialFloat f{0.0f}; f = 1.0f如果你写了SpecialFloat f{0.0f}; f = 1.0f就可以了。 SpecialFloat f{0.0f}; f = 1.0f [Demo] . SpecialFloat f{0.0f}; f = 1.0f [演示]

The line SpecialFloat f = 1.0f;SpecialFloat f = 1.0f; is doing copy initialization (1) .正在做 复制初始化 (1)

Initializes an object from another object.从另一个 object 初始化一个 object。
Syntax句法
T object = other; T object = 其他; (1) (1)

In your code T is SpecialFloat , a class type, and other is a float (not T or derived from T ).在您的代码中, TSpecialFloat ,是 class 类型,而otherfloat (不是T或派生自T )。

The effects of copy initialization are:复制初始化的效果是:
... ...
If T is a class type, and the cv-unqualified version of the type of other is not T or derived from T [...] user-defined conversion sequences that can convert from the type of other to T are examined and the best one is selected through overload resolution.如果 T 是 class 类型,并且other的类型的 cv 非限定版本不是 T 或派生自 T [...] 可以从other的类型转换为 T 的用户定义的转换序列,则检查最佳一个是通过重载决议选择的。 The result of the conversion, which is a rvalue temporary [...] of the cv-unqualified version of T if a converting constructor was used, is then used to direct-initialize the object.如果使用了转换构造函数,则转换结果是 T 的 cv 非限定版本的临时右值 [...],然后用于直接初始化 object。

User-defined conversions from float to SpecialFloat should be examined.应该检查用户定义的从floatSpecialFloat的转换。 However, explicit constructors are not considered for copy-initialization.但是,复制初始化不考虑显式构造函数。

Notes笔记

Copy-initialization is less permissive than direct-initialization: explicit constructors are not converting constructors and are not considered for copy-initialization.复制初始化比直接初始化更宽松:显式构造函数不转换构造函数,也不考虑复制初始化。

One way to solve this is to use direct initialization , and, if possible, with braces instead of parentheses, ie SpecialFloat f{1.0f} [Demo] .解决这个问题的一种方法是使用直接初始化,如果可能的话,使用大括号而不是括号,即SpecialFloat f{1.0f} [Demo] There's a C++ Core Guideline advising about preferring the {}-initializer syntax .有一个 C++ 核心指南建议优先使用 {}-initializer syntax Also, declaring single-argument constructors explicit is a general recommendation, so I would keep the user-declared constructor as explicit.此外,显式声明单参数构造函数是一般建议,因此我会将用户声明的构造函数保持为显式。

Another way would be to make SpecialFloat class an aggregate, by removing the user-declared constructor, and use aggregate initialization , Special float f = {1.0f};另一种方法是使SpecialFloat class 成为聚合,通过删除用户声明的构造函数,并使用聚合初始化Special float f = {1.0f}; [Demo] . [演示]

Finally, as commented by others, notice the signature of the assignment operator is SpecialFloat& operator=(const float f) , what indicates that a SpecialFloat& has to be returned.最后,正如其他人评论的那样,请注意赋值运算符的签名是SpecialFloat& operator=(const float f) ,这表明必须返回SpecialFloat& So first, update the object with m_float = f;所以首先,用m_float = f; ; ; then, return it with return *this;然后,用return *this;返回它. .

There are couple of issues as below.有几个问题如下。

SpecialFloat f = 1.0f;

Means you are trying to assign a float value to a SpecialFloat object.表示您正在尝试将浮点值分配给 SpecialFloat object。 This works if constructor of SpecialFloat takes a float argument and if the constructor is not marked as explicit.如果 SpecialFloat 的构造函数采用浮点参数并且构造函数未标记为显式,则此方法有效。 But in your code, you marked the constructor as explicit.但是在您的代码中,您将构造函数标记为显式。 So object is not getting created and throwing error.所以 object 没有被创建并抛出错误。 If you want to know more about explicit constructor, read What does the explicit keyword mean?如果您想了解有关显式构造函数的更多信息,请阅读显式关键字是什么意思?

Assignment operator overload function should return SpecialFloat object.赋值运算符重载 function 应返回 SpecialFloat object。 You are not returning any thing which is wrong.你没有返回任何错误的东西。 It should return SpecialFloat object as below.它应该返回 SpecialFloat object,如下所示。

SpecialFloat& SpecialFloat::operator=(const float f)
{
    m_float = f;
    return *this;
}

Your understanding about assignment operator overloading function call is wrong.您对赋值运算符重载 function 调用的理解是错误的。 Assignment operator overloading function will be called when you are trying to assign an object to already created object.当您尝试将 object 分配给已创建的 object 时,将调用重载 function 的赋值运算符。

SpecialFloat f = 1.0f;

Above statement is trying to create an object.上面的语句试图创建一个 object。 So Assignment operator overloading function won't be called in this case.因此在这种情况下不会调用重载 function 的赋值运算符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM