簡體   English   中英

c ++隱式轉換規則

[英]c++ implicit conversion rules

我試圖理解常規或成員函數調用中c ++自動和顯式轉換的規則。 我編寫了以下代碼,但編譯失敗:

#include <iostream>
#include <string>

using namespace std;

class testExplicit {
    public:
        int intval;
        short shortval;
        double doubleval;
        char charval;
        string strval;
        testExplicit(int a1, short a2, double a3, char a4, string& a5):
            intval(a1),shortval(a2),doubleval(a3),charval(a4),strval(a5){}

        void getVal(int& a) { a = intval; cout << "IntVal\n"; }
        //        void getVal(short& a) { a = shortval; cout << "Short Val\n"; }
        //        void getVal(double& a) { a = doubleval; cout << "Double Val\n"; }
        //        void getVal(char& a) { a = charval; cout << "Char Val\n"; }
        //        void getVal(string& a) { a = strval; cout << "String Val\n"; }

};

int main( int argc, char **argv ) { 
    string s ("test Str");

    testExplicit test (100,10,10.05,5,s);

    int i;
    char c;
    double d;
    short f;
    test.getVal(i);
    test.getVal(c);
    test.getVal(d);
    test.getVal(f);

    return 0;
}

但是,我可以得出結論,函數只需要精確的匹配參數嗎? 我記得讀過自動轉換是根據轉換規則發生的。 有些人可以對正確的規則有所了解嗎?

這是錯誤:

test.cpp: In function 'int main(int, char**)':
test.cpp:38: error: no matching function for call to 'testExplicit::getVal(char&)'
test.cpp:17: note: candidates are: void testExplicit::getVal(int&)
test.cpp:39: error: no matching function for call to 'testExplicit::getVal(double&)'
test.cpp:17: note: candidates are: void testExplicit::getVal(int&)
test.cpp:40: error: no matching function for call to 'testExplicit::getVal(short int&)'
test.cpp:17: note: candidates are: void testExplicit::getVal(int&)

謝謝

void getVal(int& a);

此函數通過引用獲取int 你必須傳遞一個int 這類似於你有一個功能的方式

void getVal(int* a);

你需要傳遞一個指向int的指針(不是指向short或任何其他類型的指針)。

這樣做的一個原因是您可以從函數中修改int 為了允許您將另一種類型的對象(例如, short )傳遞給此函數,必須在運行時創建short類型的臨時對象,並且必須傳遞對該臨時對象的引用。

這可能不太理想,因為您可能會意外地最終傳遞錯誤類型的對象(例如, short )並期望它被函數修改,而實際上int類型的臨時副本將被函數修改,而不是原來的short

但是,您可以將const引用綁定到臨時對象,因此如果您的函數被聲明為

void getVal(const int& a);

你可以將任何可轉換為int類型傳遞給它。 這是有道理的,因為函數不能修改引用的對象(因為它是一個const引用),所以“oops,我不小心修改了一個臨時對象”問題不存在。

轉換時也可以進行轉換,但這也是有意義的:當你按值傳遞時,無論如何都必須復制(通過值傳遞給函數的副本),因此轉換可以作為該副本的一部分。

問題是如果需要隱式轉換,則會創建一個臨時變量。 您不能對臨時變量進行非const引用,因此您需要使您的成員函數為void getVal(const int &a)void getVal(int a)

應避免隱式轉換。 C ++是一種強類型語言,為您希望接受的類型創建函數,使用模板或將類型顯式轉換為其他類型等等要好得多。

構造函數轉換或使用static_cast<>dynamic_cast<>reinterpret_cast<>是一些選項,具體取決於您需要將類型從一個轉換為另一個時的情況。

模板可以讓您更輕松地處理多種類型。

template<typename T>
void getVal(const T& a)
{
     // do something
}

通過引用傳遞意味着,為相同類型創建別名。 所以嘗試將void getVal(int& a)更改為void getVal(int a) ,以便為不同的傳遞參數類型的其他函數調用工作

通過創建rvalue(臨時)來完成隱式轉換,並且rvalues不能綁定到非const引用。 這就是它無法正常工作的原因。 另一方面,如果您更改簽名以通過值或常量引用獲取參數,那么它將起作用:

void f( int a ) { std::cout << a << std::endl; }
void g( const int& b ) { std::cout << b << std::endl; }
int main() {
   char c = 'a'; // note that this the ASCII value of 'a'
   f( c );
   g( c );
   short s = 4; 
   f( s );
   g( s );
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM