1. 程式人生 > >型別轉換函式與轉換建構函式

型別轉換函式與轉換建構函式

1. 隱式型別轉換規則

編譯器的預設隱式型別轉換規則:
這裡寫圖片描述
先看個例子:

short s = 'a';
unsigned int ui = 1000;
int i = -2000;
double d = i;

//自己先想一下輸出結果,會是什麼
cout << "d = " << d << endl;
cout << "ui + i = " << ui + i << endl;
cout << "sizeof(s + 'b') = " << sizeof(s + 'b') <<endl;

編譯執行結果:

d = -2000
ui + i = 1000
sizeof(s + 'b') = 4

為什麼會是這樣??? 為什麼不是 ui + i = -1000
因為編譯器做了隱式型別轉換。
看明白了嗎?那想必你也就明白了為什麼sizeof(s + ‘b’) = 4 了吧。

2. 轉換建構函式:

構成:(1)、首先是一個類的建構函式
(2)、有且僅有一個引數
(3)、引數型別是 基本型別 或者 其他類型別
轉換:
相當於C語言風格中的隱式型別轉換,比如:
int i = 1.5; //就是隱式轉化成了i = (int)1
所以這裡的類Test t = 100; // 就是t = Test(100);

#include <iostream>
#include <string> using namespace std; class Test { int mValue; public: Test() { mValue = 0; } Test(int i) // 轉換建構函式 { mValue = i; } Test operator + (const Test& p) { Test ret(mValue + p.mValue); return ret; } int
value() { return mValue; } }; int main() { Test t; t = 5; // t = Test(5); Test r; r = t + 10; // r = t + Test(10); cout << "r.value() = " << r.value() << endl; return 0; }

猜一下能編譯通過嗎?如果能通過,執行結果是多少?
編譯執行結果:

r.value() = 15

為了避免隱式轉換帶來bug,所以在專案中通常使用關鍵字explicit杜絕編譯器的隱式轉化,轉換建構函式被explicit修飾時只能進行顯示轉換。

3. 型別轉換函式

現在我們來想一個問題, 一個基礎資料型別 和 類型別 之間能不能進行相互轉換?兩個類型別之間能不能進行相互轉換?
示例1:

#include <iostream>
#include <string>

using namespace std;

class Test
{
    int mValue;
public:
    Test(int i = 0)
    {
        mValue = i;
    }
    int value()
    {
        return mValue;
    }
    operator int ()  // 過載int型別轉換函式
    {
        return mValue;
    }
};

int main()
{   
    Test t(100);
    int i = t;   // 把一個類型別賦值給一個int型別

    cout << "t.value() = " << t.value() << endl;
    cout << "i = " << i << endl;

    return 0;
}

示例2:

#include <iostream>
#include <string>

using namespace std;

class Test;

class Value
{
public:
    Value()
    {
    }
    explicit Value(Test& t)  // 有explicit關鍵字修飾的轉換建構函式,使用時需要顯式呼叫
    {
    }
};

class Test
{
    int mValue;
public:
    Test(int i = 0)
    {
        mValue = i;
    }
    int value()
    {
        return mValue;
    }
    operator Value() // 過載Value類型別
    {
        Value ret;
        cout << "operator Value()" << endl;
        return ret;
    }
};

int main()
{   
    Test t(100);
    Value v = t;

    return 0;
}

因為無法抑制隱式的型別轉換函式呼叫,或者型別轉換函式可能與轉換建構函式衝突,所以在專案中通常使用Type toType()的共有成員函式代替型別轉換函式。

相關推薦

C++中類的建構函式複製建構函式

1 相關定義 1.1 建構函式 建構函式是類的特殊的成員函式,只要建立類型別的新物件,都要執行建構函式。建構函式的工作是保證每個物件的資料成員具有合適的初始值。建構函式的名字與類的名字相同,並且不能指定返回型別。像其他任何函式一樣,它們可以沒有形參,也可以定義多個形參。 1

建構函式預設建構函式

在C++中,結構體與類是相似的,他們可以互相進行繼承操作 比如我們構造一個類A和一個繼承A的結構體B class A { public: int a; }; struct B:A { }; 他們之間可以是相互的繼承關係,因此執行以下操作是被允許的 B b;

複製建構函式拷貝建構函式

對一個簡單變數的初始化方法是用一個常量或變數初始化另一個變數,例如:   int m = 80;   int n = m;   我們已經會用建構函式初始化物件,那麼我們能不能象簡單變數的初始化一樣,直接用一個物件來初始化另一個物件呢?答案是肯定的。我們以前面定義的Point類為例:   Point pt1(

型別轉換函式轉換建構函式

1. 隱式型別轉換規則 編譯器的預設隱式型別轉換規則: 先看個例子: short s = 'a'; unsigned int ui = 1000; int i = -2000; double d = i; //自己先想一下輸出結果,會是什麼 cout

C++中struct也有建構函式解構函式,也可以有訪問型別控制以及結構體大小,類大小

C++中struct也有建構函式與解構函式,也可以有訪問型別控制,可以用private關鍵字。如下所示: #include <iostream> struct point { public: point():x_(0.0),y_(0.0

C++(建構函式解構函式

C++(建構函式與解構函式) 1. 建構函式 用於對類的物件的初始化,建構函式名與類名相同。 可在類內直接定義,也可在類內宣告類外定義(定義時在函式名前加類名::)。 建構函式無返回值型別。 class C { public: C(int a,int b);//類

Java的建構函式解構函式(筆記1)

已Mydate為例: package text1; public class MyDate { int year; int month; int day; //1.建構函式 public MyDate(int y,int m,int d) { year = y; mon

請為CMyString型別編寫建構函式、copy建構函式、解構函式和賦值運算子函式

如下為型別CMyString的宣告,請為該型別編寫建構函式、copy建構函式、解構函式和賦值運算子函式。 1 class CMyString 2 { 3 public: 4 CMyString(const char* pData = nullptr); 5 CMyS

《C++反彙編逆向分析技術揭祕》讀書總結——建構函式解構函式

建構函式的必要條件: 這個函式的呼叫,是這個物件在作用域內的第一次成員函式呼叫,看this指標即可以區分物件,是哪個物件的this指標就是哪個物件的成員函式。 使用thiscall呼叫方式,使用ecx傳遞this指標; 返回值為this指標。 解構函式的必要條件: 這

C++知識積累:運算子過載時建構函式解構函式呼叫次數不一致的問題

在學習運算子過載的時候自己寫了這樣一段程式: class Stu { public: Stu() { std::cout<<"Stu No parameter constructor called!"<<

單繼承派生類建構函式解構函式順序

派生類建構函式形式: 派生類建構函式 (引數表):基類建構函式(引數表) 類物件成員1(引數表)... 類物件成員n(引數表)//只能用表示式的方式對類物件成員進行初始化 {...派生類自定義的資料成員初始化} 在派生類中,首先呼叫基類的建構函式,其次呼叫

Java 訪問修飾符預設建構函式

                                         第一章:訪問修飾符        Java訪問修飾符包括private,default,protected和public。含義分別表示私有的,預設的,受保護的和公有的訪問修飾符。這些訪問修飾符

建構函式解構函式的呼叫時間

    建構函式與解構函式是被編譯器隱式呼叫的。這些函式的呼叫時間取決於程式執行進入和離開例項化物件的作用域的順序。通常,解構函式的呼叫順序和對應建構函式的呼叫順序相反。但是,物件的儲存類別可以改變解構函式的呼叫順序。    在全域性作用域內定義的建構函式在該檔案中任何其他函

建構函式解構函式

類的建構函式是在建立類的物件時有系統自動執行的函式,一般把類的初始化工作放在這裡,客戶無法呼叫該函式。  類解構函式是類的物件在銷燬是執行的函式,一些收尾工作放在這裡,比如釋放記憶體等,客戶無法呼叫  

建構函式解構函式的示例

class Student { public: Student(); Student(int); private: double score, count; };     建構函式是一個很神奇

C/C++面試題:建構函式解構函式

建構函式與解構函式的一道小題 下面程式的輸出是什麼? #include<iostream> using namespace std; class TestClass{ cha

解析c++建構函式解構函式

目錄 建構函式的定義 定義:建構函式是一種特殊的成員函式,對物件進行初始化的函式。 建構函式的特點 建構函式名字必須與類名相同。 建構函式不具有任何型別,沒有返回值。 在建立類的物件的時候,系統會自動呼叫建構函式。 如果使用者沒有定義建構函式,系

C++繼承詳解之二——派生類成員函式詳解(函式隱藏、建構函式相容覆蓋規則)

  在這一篇文章開始之前,我先解決一個問題。   在上一篇C++繼承詳解之一——初探繼承中,我提到了在派生類中可以定義一個與基類成員函式同名的函式,這樣派生類中的函式就會覆蓋掉基類的成員函式。   在譚浩強的C++程式設計這本書第十一章,351頁最下面有這麼

建構函式解構函式的比較

建構函式的作用:建立並初始化物件,即為物件成員變數賦初始值。 特點: 1、建構函式名與類名相同。 2、建構函式沒有返回值。 3、建構函式不可以被直接呼叫。 4、定義了類沒有定義建構函式時C++

右值引用移動建構函式的一點理解

說明:右值引用是c++11中的新特性,本來c++中是有一個左值引用的,引入右值引用後,多了很多概念,再看prime的時候,就覺得似乎讓c++更繁瑣了。偶然在知乎上看到這個話題,於是有了一點理解,遂記錄於此。知乎連結 大象與冰箱 我們還是從大象與冰箱的