在C转换算++(Conversion Operators in C++)

2019-07-05 00:50发布

请帮助我了解究竟是如何转换运营商在C ++的工作。 我这里有一个简单的例子,我想了解,虽然它是不是很清楚如何转换实际上是由编译器发生。

class Example{
public:
    Example();
    Example(int val);
    operator unsigned int();
    ~Example(){}
private:
    int itsVal;
};

Example::Example():itsVal(0){}

Example::Example(int val):itsVal(val){}

Example::operator unsigned int (){
    return (itsVal);
}

int main(){
    int theInt = 5;
    Example exObject = theInt; // here 
    Example ctr(5);
    int theInt1 = ctr; // here
    return 0;
}

Answer 1:

您可以通过代码调试器行走(和/或将断点上每个建设者和运营商的),看看哪建设者和运营商正在通过线调用。

因为你没有明确定义它们,编译器还为你的类隐藏/默认的拷贝构造函数和赋值运算符。 如果你想使用调试器看到/被调用的时候,他们可以明确地定义这些(如下图)。

Example::Example(const Example& rhs)
: itsVal(rhs.itsVal)
{}

Example& operator=(const Example& rhs)
{
    if (this != &rhs)
    {
        this->itsVal = rhs.itsVal;
    }
    return *this;
}


Answer 2:

int main() {
    int theInt = 5;

    /**
     * Constructor "Example(int val)" in effect at the statement below.
     * Same as "Example exObject(theInt);" or "Example exObject = Example(theInt);"
     */
    Example exObject = theInt; // 1

    Example ctr(5);

    /**
     * "operator unsigned int()" in effect at the statement below.
     * What gets assigned is the value returned by "operator unsigned int()".
     */
    int theInt1 = ctr; // 2

    return 0;
}

在声明中1的构造Example(int val)被调用。 声明为explicit Example(int val)你会得到一个编译时错误,即没有隐式转换将被允许对这种构造。

所有单参数构造函数被隐式调用如果指定的值是各自的参数类型的。 使用explicit前一个参数的构造函数的关键字禁用隐式构造函数调用,因此隐式转换。

如果构造函数声明为明确的,即explicit Example(int val)那么下面会发生每条语句。

Example exObject(theInt); // Compile time error.
Example exObject = theInt; // Compile time error.
Example exObject(Example(theInt)); // Okay!
Example exObject = Example(theInt); // Okay!

还要注意,在隐含的构造函数调用,因此隐式转换的情况下,分配的值是使用左值(的INT),它告诉我们隐式创建一个右值即未命名的对象,在编译器转换的隐式转换情况

Example exObject = theInt;

Example exObject = Example(theInt);

所以(在C ++ 11)不希望被称为左值构造看到你使用的是左值,即一个名为值theInt用于分配。 什么被调用的是右值的构造函数,因为所分配的值实际上是用左值创建的未命名的对象。 然而,这也适用,如果你有构造函数的两个左值和右值版本。

在声明中2 operator unsigned int()被调用。 简单地把它作为一个奇怪的名字一般的函数调用,事实上,当隐式转换情况可以得到自动的调用。 由该函数返回的值是在表达式分配值。 而且,由于你执行返回的值是一个int它正确地被分配到int theInt1

要精确operator unsigned int()重载()操作者即铸造操作者。 在您的情况下,它重载int因此每当的目的Example类被分配给一个int从隐式类型铸造Exampleint发生,并因此operator unsigned int()被调用。 因此,

int theInt1 = ctr;

相当于

int theInt1 = (int)ctr;


Answer 3:

Example exObject = theInt; // implicitly created copy constructor takes place
// object implicitly created from int and then copied
// it is like
Example exObject = Example(theInt);
// so it uses sequence
// Example(int) -> Example(const Example&)
int theInt1 = ctr; // operator int()

如果编译器支持拷贝构造函数的优化和返回值优化,你不会注意到

Example(const Example&)

执行,但是你可以声明拷贝构造函数是私有明白我在说什么。



Answer 4:

Example exObject = theInt; // here

此方法使用int实施例的隐式转换,通过它接受一个int非显式构造实现。

这也需要复制构造实例的可用性,即使编译器允许省略复制实例。

int theInt1 = ctr; // here

这使用于无符号整型实施例的隐式转换,通过浇铸运营商提供。

铸造运营商通常是可以避免的,因为他们往往会导致混淆代码,你可以标记单参数的构造函数明确,禁止隐式转换为类类型。 的C ++ 0x应该还添加标记转换操作的可能性显式的(所以你需要一个的static_cast调用它们 - 我的编译器不支持他们,所有的网络资源,似乎集中在显式转换为bool)。



文章来源: Conversion Operators in C++