一、類類型轉換
首先,明確什麼是類類型轉換,
內置類型存在定義了幾種自動轉換的規則,同樣地,類也有定義隱式的轉換規則。
若構造函數沒有聲明explicit且只接受一個實參,則它可以進行隱式的類類型轉換。(如何將一種類類型轉換爲另一種類類型的轉換規則)
類的構造函數默認是implicit的,可以進行隱式類類型轉換的,
explicit關鍵字只能用於修飾只有一個參數的類構造函數, 它的作用是表明該構造函數是顯示的。
二、隱式類類型轉換
首先,引入一個Person類。
#pragma once
#include<string>
#include<ctime>
#include<iostream>
using std::string;
using std::rand;
using std::cout;
using std::endl;
class Person
{
public:
Person(string str);
Person(string std, int a);
~Person();
void play_with(const Person& p);
private:
string name;
int age;
};
inline Person::Person(string str)
{
this->name = str;
srand((unsigned int)(time(NULL)));
age = rand() % 100;
}
//inline 會在編譯的時候將函數內部替換掉,從而減少函數調用的時間
inline Person::Person(string str, int a)
{
this->name = str;
this->age = a;
}
inline void Person::play_with(const Person& p)
{
cout << this->name << " is playing whih " << p.name;
}
Person::~Person()
{
}
然後進行調用。
1.xiaom初始化的時候,使用的是先構造函數這裏進行了隱式轉換,直接調用的構造函數不會調用拷貝構造函數。
2.play_with(b)運行的時候,編譯器會用給定的string自動創建一個Persion對象,作爲臨時對象傳給paly_with。
3.對於xiaoc的初始化,是將c的ASCII值作爲int型。
#include <iostream>
#include"Explicti.h"
int main()
{
string a="xiaoming";
Person xiaom = a;//隱式轉換1
string b = "xiaohong";
xiaom.play_with(b);//隱式轉換2 這裏第一個參數的是一個const類型的引用
Person xiaoc = 'c';//隱式轉換3
}
注意:
1.必須一步轉換
//將char字符數組先轉爲string,再轉換爲Person,錯誤
xiaom.play_with("xiaohong");
//先顯示轉換string,隱式轉換爲類類型
xiaom.play_with(string("xiaohong"));
//隱式轉換爲string,再顯示轉換爲類類型
xiaom.play_with(Person("xiaohong"));
2.默認不聲明,是可以隱式的。
3.需要多個參數的構造函數不能用於隱式轉換;但是也有例外,當多參數構造函數除了第一個以外都有默認實參的時候,可以對第一個參數進行隱式轉換。
三、顯示類類型轉換
在聲明中添加explicit
//在聲明中添加explicit
explicit Person(string str);
string a="xiaoming";
Person xiaom = a;//隱式轉換1 不可以轉換
string b = "xiaohong";
xiaom.play_with(b);//隱式轉換2 不可以轉換
Person xiaoc = 'c';//隱式轉換3 仍然可以
當然即使有explicit我們也可以顯示的轉換。
string a = "xiaoming";
Person xiaom = static_cast<Person>(a);//隱式轉換1
string b = "xiaohong";
xiaom.play_with(static_cast<Person>(b));//隱式轉換2
注意:
1.在類內部聲明,不能在類外部定義的時候不應該重複
explicit inline Person::Person(string str)
{
this->name = str;
srand((unsigned int)(time(NULL)));
age = rand() % 100;
}
2.explicit的構造函數只能用於直接初始化。 (除非你提取進行了顯示轉換)
3.explicit只對有一個參數構造函數有效;
但是也有例外,當多參數構造函數除了第一個以外都有默認實參的時候,explicit有效。
四、類型轉換運算符
既然存在將實參類型轉換爲類類型,那麼也能定義將類類型轉換爲其他類型,這就是類型轉換運算符。
類型轉換運算符是類的一種特殊成員函數,它負責將一個類類型的值轉換成其他類型。
類型轉換運算符
operator type() const;
這裏type可以面向任何可以作爲函數返回類型的類型。因此,不允許轉換成數組或函數類型,但是允許轉換爲指針(包括數組指整和函數指針)或者引用類型。
類型轉換運算符不應該改變待轉換對象的內容,一般被定義成const成員。
對於Person類,將person類轉換爲string類型。
operator string () const;
inline Person::operator string() const
{
return this->name + std::to_string(this->age);
}
string res = xiaom ;
cout << res << endl;
這裏會將Person類轉換爲string類型。
注意:
1.類型轉換運算符不能指定返回類型。
2.參數列表需要爲空
3.類型轉換運算符的定義中的返回類型需要時type類型。
inline Person::operator int *() const
{
return 42;//這是錯誤的,不能正常轉換爲int指針類型
}
4.一般聲明爲const成員。