[C++]类的自动类型转换和转换操作符

1.当构造函数只接受一个参数时,则该类可以与该参数类型相同的值转换。

看下面这个简单的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Woo.h file
#ifndef WOO_H
#define WOO_H
 
class Woo{
private:
	double mm;
public:
	/*explicit*/ Woo(double a);
	Woo() {mm=0;};
	void show();
 
	//operator double() const;
};
 
#endif
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Woo.cpp file
#include "stone.h"
#include <iostream>
using namespace std;
 
Woo::Woo(double a)
{
	mm = a;
}
 
void Woo::show()
{
	cout << "show function: " << mm << endl;
}
 
/*
Woo::operator double() const
{
	return double(mm);
}
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// main.cpp file
#include "stone.h"
#include <iostream>
using namespace std;
 
int main()
{
	Woo a;
	a = 13.3;
	a.show();
 
	/*
	Woo a(13.3);
	double b = a;
	cout << b << endl;
	*/
}

运行结果:

zhuanhuan

其实,此处重点还是因为在赋值时,创建了一个该类的临时变量,然后将临时变量赋值给该类变量。

如果想要关闭这个特性,可以使用explicit关键字,只需要在类声明中的构造函数前加上explicit即可,如:

1
explicit Woo(double a);

此时我在VS2008下显示报错:

error C2679: 二进制“=”: 没有找到接受“double”类型的右操作数的运算符(或没有可接受的转换)

2.C++类型转换操作符

在上面,符合条件时,可以将double赋值给一个类类型,那反过来行吗?

可以,不过此时要使用C++的转换操作符函数。

转换函数是用户定义的强制类型转换,可以像使用强制类型转换一样使用它们。

转换函数的使用方法:

operator typeName();

typeName是要转换为的类型。

注意以下几点:

①.转换函数必须是类方法。

②.转换函数不能指定返回类型。

③.转换函数不能有参数。

我们还是使用上面的例子:
直接把注视掉的地方,把注视符号去掉即可。

运行结果:

zhuanhuan2

在网上还有另外两篇讲到了转换函数:

1.http://c.chinaitlab.com/example/837012.html

2.http://topic.csdn.net/u/20070626/17/34235b2e-212b-446f-8ca7-031a1fa5c39c.html

OK,结束~~

发布者

Tanky Woo

Tanky Woo,[个人主页:https://tankywoo.com] / [新博客:https://blog.tankywoo.com]

《[C++]类的自动类型转换和转换操作符》有6个想法

  1. Hi Tanky
    explicit 用来指定不使用隐式类型转换.你文中的1点其实即使复制构造函数,对象在赋值的时候默认调用复制构造函数,
    a = 13.3;相当于
    a=Woo(13.3);
    在构造函数前修饰以关键词explicit的时候,隐式转换已经关闭,不会自动调用复制构造函数,所以必须明确写为a=Woo(13.3)才行。可以把输出语句放到构造函数中可以执行过程更清晰点。
    ^-^

    1. a=13.3和a=Woo(13.3)在关闭explicit特性下还是有些不同的吧?
      第二个相当于强制转换了,而第一个也不能通过编译。

      你这里写的“其实即使复制构造函数”即使是打错字了吗?我有点读不通。

    2. 1.即使打错了,是即是。
      2.在没有以explict修饰的情况下,假如你没有定义=操作符,调用=操作符的时候,默认就是调用复制构造函数,你文中就是这种情况。在这种情况下a=13.3和a=Woo(13.3)实质是一样的。
      你可以试试以下代码, 会发现问题。
      class A{
      public:
      A()
      {};
      A(int t)
      {
      cout<<"Constucting…."<<endl;
      a=t;
      cout<<"a="<<a<<endl;
      }
      private:
      int a;
      };
      int main()
      {
      cout<<"a=12:"<<endl;
      A a;
      a=12;
      cout<<"A b(12)"<<endl;
      A b(12);
      cin.get ();
      }

      a=13,的整个过程其实是,A(int t)先使用13建立一个对象,然后将这个对象赋值给a,这就是所谓隐式转换。

      当你使用explicit修饰的时候,也就把隐式转换关闭了,也就是说你告诉编译器,只有我显示指出调用该构造函数才调用。所以,在有explicit的时候a=13就不能通过了,因为编译器不会自动调用构造函数来帮你完成隐式转换。

    3. 嗯,a = 13.3和a = Woo(13.3)一个是隐式,一个是显式,和我上面说的一样。。。这就是唯一的区别。。。explicit关闭的也就是这个特性。当然,这其中在未explicit下都调用了单参数构造函数。

发表评论

电子邮件地址不会被公开。 必填项已用*标注