类型转换在我们平常代码中经常会遇到,比如: 我们在进行运算的时候,我们知道只有类型相同的数据才能进行运算,比如: 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. 类类型转化为普通类型 --> 这个其实就是定义一个重载函数,我们根据需求,希望类类型转化为什么样的类型,那就重载哪个类型的数据,此函数不需要写返回值类型,编译器会根据你重载的类型自己判断。
我们只需要根据需要在函数中返回一个对应类型的数据即可。(可以是类内属性的值,也可以是别的自己定义的值)