c++运算符重载(6) -- 类型转换

类型转换在我们平常代码中经常会遇到,比如: 我们在进行运算的时候,我们知道只有类型相同的数据才能进行运算,比如:  10 + 10.0,  一个int和double类型的数据相加,编译器会自动将10转换为double类型,即10.0。

如果是基本数据类型,在计算过程中编译器知道给你如何转换,那如果是你自己定义的类对象呢? 编译器是不知道如何转换的。这时候如果想要实现类型转换我们就得重载类型转换运算符。 

类型转换有三种:   

普通类型转化为类类型 

class Human {
public:
	Human(int age, int salary, const char* name);
	Human(int age);

	friend ostream& operator<<(ostream& os, const Human& human);
	friend Human operator+(const Human& man1, const Human& man2);
private:
	int age;
	int salary;
	string name;
};

int main(void) {
	Human man1(18, 15000, "ABC");

	Human man2 = 25;

	Human man3 = man1 + 100;

	cout << man3 << endl;

	system("pause");

	return 0;
}

Human::Human(int age, int salary, const char* name)
{
	cout << __FUNCTION__ << endl;
	this->name = name;
	this->salary = salary;
	this->age = age;
}

Human::Human(int age)
{
	cout << __FUNCTION__ << endl;
	this->name = "未命名";
	this->age = age;
	this->salary = 0;
}

ostream& operator<<(ostream& os, const Human& human) {
	cout << __FUNCTION__ << endl;
	os << "姓名:"   << human.name   << " 年龄:" << human.age 
	   << " 薪水: " << human.salary << endl;

	return os;
}

Human operator+(const Human& man1, const Human& man2) {
	cout << __FUNCTION__ << endl;
	int age_tmp = man1.age + man2.age;
	int salary_tmp = man1.salary + man2.salary;

	return Human(age_tmp, salary_tmp, man1.name.c_str());
}

代码分析: 

1.   将类类型转化为普通类型也是需要使用函数来依靠的,这个函数就是Human(int age); 就是只有一个参数的构造函数,也可以成为转换构造函数(类型转换嘛) 

2.  当我们定义转换构造函数之后,在需要将普通类型转化为类类型的时候,编译器就会调用这个函数,根据传入的数据,进行相关赋值,然后编译器会自己返回一个类对象。 

3.   上面代码中,Human man1 = 100;  Human man3 = man1 + 100;    这两种情况都会调用转换函数,然后将100转换成Human类对象进行运算。(将100作为参数传入转换函数中,进行相应操作之后,编译器会自动返回一个Human类对象)

4.   Human man1 = 100; // 这句话代码的执行过程: 先调用Human(int age);函数将100转换成Human类型,然后调用拷贝构造函数,将返回的Human对象中的数据拷贝到man1当中。

5.   Human man3 = man1 + 100; // 其实和上面的步骤是类似的,只是将100转换为Human类型的对象之后,再调用+运算符重载函数,对两个对象相加,再将结果拷贝到man3中。

6.  当定义了转换构造函数,我们就能进行强制类型转换了,例:  (Human)100; 这段代码就会调用转换构造函数,将100强制转换为Human类。

7.  如果我们想将多种类型的数据转换为Human类,那么就需要定义多个转换构造函数,定义不同的参数类型,这样就可以对多种类型进行转换。 

8.  其实很好理解,当编译器遇到普通类型需要转换成类类型的时候,其实你就可以看成,将普通类型的数值作为参数,调用转换构造函数,又构造了一个对象。 

类类型转化为普通类型 

class Human {
public:
	Human(int age, int salary, const char* name);
	Human(int age);

	friend ostream& operator<<(ostream& os, const Human& human);
	friend Human operator+(const Human& man1, const Human& man2);
	operator int()const;
private:
	int age;
	int salary;
	string name;
};

int main(void) {
	Human man1(18, 15000, "ABC");

	int age = (int)man1 + 10;

	cout << age << endl;

	system("pause");

	return 0;
}

Human::Human(int age, int salary, const char* name)
{
	cout << __FUNCTION__ << endl;
	this->name = name;
	this->salary = salary;
	this->age = age;
}

Human::Human(int age)
{
	cout << __FUNCTION__ << endl;
	this->name = "未命名";
	this->age = age;
	this->salary = 0;
}

Human::operator int() const
{
	return age;
}

ostream& operator<<(ostream& os, const Human& human) {
	cout << __FUNCTION__ << endl;
	os << "姓名:" << human.name << " 年龄:" << human.age
		<< " 薪水: " << human.salary << endl;

	return os;
}

Human operator+(const Human& man1, const Human& man2) {
	cout << __FUNCTION__ << endl;
	int age_tmp = man1.age + man2.age;
	int salary_tmp = man1.salary + man2.salary;

	return Human(age_tmp, salary_tmp, man1.name.c_str());
}

代码分析:   

1.  operator int();    // 是类类型转化为普通类型的重载函数,它不需要返回值,编译器在执行结束后会自动根据重载的类型返回一个此类型的值,比如:  上面函数返回int类型。 

2. 这个函数其实非常简单,我们只需要在重载函数中返回一个我们需要的值即可。 其实将类类型转换为普通类型就是这样,类对象调用函数,我们根据代码的需求返回对应类型的数据。

比如:  上面代码的需求,我们将类类型转换为普通类型的时候,希望转换为age的值,因为age是int类型,所以我们要对int类型进行重载,因为我们希望得到age的值,那么就返回一个对象age属性的值。

3. 其实所谓的类类型转化为普通类型,就是根据需要由函数返回一个类对象中的相应类型的数据。 

 4.  我们同样可以使用强制类型转换,将类对象转换为普通类型。 如:  (int) man1;  这时候编译器就会调用operator int()函数,他会返回一个man中int类型的数据。

5.   代码中int age = man1 + 10;如果不对man1进行强制转换,编译器会默认将10转换为Human类,会去调用普通类型转换为类类型的函数,但是我们没有定义所以会出问题。

所以就需要对man1进行强制类型转换成int, int age = (int)man1 + 10; 

6.  为什么编译器会默认认为是将10转化为Human类型,其实这种情况在普通类型中也由这种情况,比如我们上面提到的,10+10.0, 这个隐式转换是将int转化为double,而不是将double转换为int,所以说隐式转换,编译器默认会认为将小类型转化为大类型,这样比较安全。

如果要想大类型转化为小类型,就得需要强制类型转换。 

 

类类型转化为其它的类类型 

class Boy;

class Human {
public:
	Human(int age, int salary, const char* name);
	Human(const Boy& boy);

	friend ostream& operator<<(ostream& os, const Human& human);
	friend Human operator+(const Human& man1, const Human& man2);
private:
	int age;
	int salary;
	string name;
};

class Boy {
public:
	Boy(string name,int age,int salary, int look);

	friend Human::Human(const Boy& boy);
private:
	int age;
	int salary;
	int look;
	string name;
};

int main(void) {
	Human man1(18, 15000, "ABC");
	Boy boy("boy",26,50000,10);

	man1 = boy;

	cout << man1 << endl;

	system("pause");

	return 0;
}

Human::Human(int age, int salary, const char* name)
{
	cout << __FUNCTION__ << endl;
	this->name = name;
	this->salary = salary;
	this->age = age;
}

Human::Human(int age)
{
	cout << __FUNCTION__ << endl;
	this->name = "未命名";
	this->age = age;
	this->salary = 0;
}

Human::Human(const Boy& boy)
{
	this->name = boy.name;
	this->age = boy.age;
	this->salary = boy.salary;
}


ostream& operator<<(ostream& os, const Human& human) {
	cout << __FUNCTION__ << endl;
	os << "姓名:" << human.name << " 年龄:" << human.age
	   << " 薪水: " << human.salary << endl;

	return os;
}

Human operator+(const Human& man1, const Human& man2) {
	cout << __FUNCTION__ << endl;
	int age_tmp = man1.age + man2.age;
	int salary_tmp = man1.salary + man2.salary;

	return Human(age_tmp, salary_tmp, man1.name.c_str());
}

Boy::Boy(string name,int age, int salary, int look)
{
	this->name = name;
	this->age = age;
	this->salary = salary;
	this->look = look;
}

代码分析: 

1.  代码中,我们将Boy类赋值给了Human类,在赋值的时候, 编译器会调用我们写的构造函数将Boy类转化为Human类,然后再进行赋值操作。

2.  其实这种转换也很简单,就是将boy对象作为参数传入构造函数,然后进行相应的操作,又构造了一个Human类的对象,然后再进行赋值。

 

 

总结:  

1. 普通类型转换为类类型 -->  就是将调用只有一个参数的构造函数,将这个普通类型的数据作为实参,进行相应的操作之后,构造一个对象返回,实现普通类型到类类型的转换。  

2. 类类型转化为其它的类类型 -->   其实和上面的过程是一样的,只不过参数变为了别的类型的对象了。

3.  类类型转化为普通类型  -->  这个其实就是定义一个重载函数,我们根据需求,希望类类型转化为什么样的类型,那就重载哪个类型的数据,此函数不需要写返回值类型,编译器会根据你重载的类型自己判断。

我们只需要根据需要在函数中返回一个对应类型的数据即可。(可以是类内属性的值,也可以是别的自己定义的值) 

 

你可能感兴趣的:(c++,开发语言)