繁体   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