这篇文章主要为大家详细介绍了C++中类的转换函数,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
只有接受一个参数(其他参数有默认值)的构造函数才能用作转换构造函数。
在C++中,接受参数的构造函数提供了将与参数类型相同的值转换为类的蓝图。因此,下面的构造函数用于将double类型的值转换为Stonewt类型:
Stonewt(double lbs) // double转Stonewt的模板
也就是说,您可以编写以下代码:
Stonewt myCat; // 创建一个Stonewt对象myCat = 19.6; // 使用Stonewt(double)将19.6转换为Stonewt对象
这个过程称为隐式转换,因为它是自动的,没有显式的强制类型转换。
使用构造函数作为自动类型转换似乎是一个很好的特性。然而,当程序员对C++有了更多的经验后,他们会发现这种自动特性并不总是可取的,因为它会导致意想不到的类型转换。因此,C++添加了关键字explicit来关闭这个自动特性。也就是说,构造函数可以这样声明:
explicit Stonewt(double lbs) // 不允许隐式转换
这将关闭上例中引入的隐式转换,但仍允许显式转换,即显式强制转换:
Stonewt myCat;myCat = 19.6; // 不允许,因为Stonewt(double)声明为explicitmyCat = Stonewt(19.6); // OK,一个显示地转换myCat = (Stonewt)19.6; // OK,原始地显示类型转换
编译器什么时候会使用Stonewt(double)函数?
如果在声明中使用了关键字explicit,则Stonewt(double)将仅用于显式强制类型转换,否则它也可用于以下隐式转换:
将Stonewt对象初始化为double值时。如:Stonewt st(1.23);将double值赋给Stonewt对象时。如:Stonewt st; st = 1.23;将double值传递给接受Stonewt参数的函数时。如:display(Stonewtamp; st);-gt; display(1.23);返回值被声明为Stonewt的函数试图返回double值时。如:Stonewtamp; go(){ return 1.23; }在上述任意一种情况下,使用可转换为double类型的内置类型时。如:Stonewtamp; go() { return 123; }
您可以将数字转换为Stonewt对象。可以反过来换算吗?也就是说,是否有可能将Stonewt对象转换为double值,如下所示?
Stonewt wolfe(285.7);double host = wolfe;// 可以吗
您可以这样做,但不能使用构造函数。构造函数仅用于从某种类型转换为类类型。要做相反的转换,必须使用特殊的C++运算符函数;;转换功能。
函数是用户定义的转换类型,您可以像使用转换类型一样使用它们。例如,如果定义了从Stonewt到double的转换函数,则可以使用以下转换:
Stonewt wolfe(285.7);double host = double (wolfe); // syntax #1double thinker = (double) wolfe; // syntax #2也可以让编译器来决定如何做:Stonewt wells(20, 3);double star = wells; // 隐式使用转换函数
编译器发现右边是Stonewt类型,左边是double类型,所以会检查程序员是否定义了与此匹配的转换函数。(如果找不到这样的定义,编译器将生成一条错误消息,指出Stonewt不能赋给double。)
要创建转换函数并将其转换为typeName类型,您需要使用以下形式的转换函数:
operator typename();//没有返回类型,没有参数
请注意以下几点:
转换函数必须是类方法转换函数不能指定返回类型转换函数不能有参数
在类的头文件中定义:
operator int() const;operator double() const;
实施代码:
......// construct Stonewt object from stone, double valuesStonewt::Stonewt(int stn, double lbs) {stone = stn;pds_left = lbs;pounds = stn * Lbs_per_stn + lbs;}......// conversion functionsStonewt::operator int() const {return int(pounds + 0.5);}Stonewt::operator double() const {return pounds;}
使用:
Stonewt poppins(9, 2.8);// 9 stone, 2.8 poundsdouble p_wt = poppins;// implicit conversioncout lt;lt; "Convert to double =gt; ";cout lt;lt; "Poppins: " lt;lt; p_wt lt;lt; " pounds.\n";cout lt;lt; "Convert to int =gt; ";cout lt;lt; "Poppins: " lt;lt; int(poppins) lt;lt; " pounds.\n";Convert to double =gt; Poppins: 128.8 pounds.Convert to int =gt; Poppins: 129 pounds.
原则上,最好使用显式转换,而不是隐式转换。在C++98中,关键字explicit不能用于转换函数,但C++11消除了这一限制。因此,在C++11中,转换运算符可以声明为显式的:
class Stonewt { ... // 转换函数 explicit operator int() const; explicit operator double() const;};
显式声明后,这些运算符在显式强制转换时被调用。
另一种方法是将转换函数替换为具有相同函数的非转换函数,但该函数只有在显式调用时才会执行。也就是说,你可以把:
Stonewt::operator int() { return int (pounds + 0.5); }替换为:int Stonewt::Stone_to_Int() { return int (pounds + 0.5); }
这样,下面的语句:
int plb = poppins; // 非法int plb1 = (int) poppins;// 合法int plb2 = int(poppins);// 合法int plb3 = poppins.Stone_to_Int(); // 合法
应该谨慎使用隐式转换函数。通常,最好选择一个只有在显式调用时才会执行的函数。
总结
本文到此为止。希望能帮到你
精彩评论