C++ explicit和implicit

一、類類型轉換

首先,明確什麼是類類型轉換,

內置類型存在定義了幾種自動轉換的規則,同樣地,類也有定義隱式的轉換規則。

若構造函數沒有聲明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成員。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章