注册 登录
编程论坛 C++教室

C++类型转换函数和指向函数的指针

lyj123 发布于 2012-11-25 07:43, 1988 次点击
程序代码:
C++学习中的问题汇总:
    C++里指向函数的指针如
#include<iostream>
using namespace std;   
int main(){
        int max(int);
        int (*p)(int)=&max;
        (*p)();
    return 0;
}
int max(int x=5){cout<<x<<endl;return x;}

为何已经声明了默认参数还是不能用指向函数的指针来调用且不传递参数。

为什么在类中定义了两个类型转换函数就出错?
#include<iostream>
using namespace std;
class T{
private:
    int a;
    double b;
public:
    T(int a,double b):a(a),b(b){}
    operator double(){return b;}
    operator int(){return a;}//这行如果注释掉编译通过,结果正确
};
int main(){
    T x(3,7.37);
    cout<<(2.1+x)<<endl;
    return 0;
}
11 回复
#2
落默仸2012-11-25 11:47
一个是整型的,一个双字节型的。你可以分开定义2个类试试看……
                 
#3
lyj1232012-11-25 12:00
对啊,一个整型一个double型,不矛盾啊?为什么不能一起定义?
#4
newdos2012-11-25 12:19
函数指针只是一个变量,对你的默认参数看不见的。编译器在编译指针那句,只会把函数地址放到指针变量中。
正常的函数调用编译器会检查默认参数,产生push指令压参,然后调用函数。

类中定义了两个类型转换函数,你认为2.1+x是该调用double那个?还是调用int那个?很明显,编译器和你一样,不知道使用哪个隐式转换。
除非你使用cout<<(2.1+x.operator double())<<endl; 显示指明。慎用类型转换函数,详情可以参拷《Effctive C++》中关于类型转换函数负作用的条款。
#5
wuxia1111112012-11-25 13:58
1)#include<iostream>
using namespace std;   
int main()
{
   int max(int x);
   int (*p)(int)=max;
   (*p)(6);//在这要传参啊
   return 0;
}
int max(int x=5)
{cout<<x<<endl;
return x;}

2)/*有两个类型转换,到底该用那个呢?调用*/
#include<iostream>
using namespace std;
class T{
private:
    int a;
    double b;
public:
    T(int a,double b):a(a),b(b)
    {}
    operator double()
    {return b;}
   operator int()
    {return a;}//这行如果注释掉编译通过,结果正确
   
};

int main(){
    T x(3,7.37);
    cout<<(2.1+x.operator int())<<endl;//这应该调用
    cout<<(2.1+x.operator double())<<endl;//调用
    return 0;
}
#6
lyj1232012-11-25 14:20
回复 4楼 newdos
2.1+x   2.1不是double型的吗?为什么编译器不会找到double型的类型转换来转换?
#7
newdos2012-11-27 11:26
2.1 + 1 = ?
2.1 + 1.0 = ?
你能说1 和 1.0的类型相同?
最后的结果是double,是因为整数可以被隐式提升为double型。
#8
liufashuai2012-11-27 16:15
第一个问题:
你搞错了,C++ 是允许默认,但是你调用的是指针函数,不是默认参数的函数

你调用max()就可以,但是调用(*p)()就不可以原因就是你的函数指针不是默认参数,当然如果你非要这样也可以:
程序代码:
#include<iostream>
using namespace std;  
int main(){
        int max(int);
        int (*p)(int=4)=&max;
        (*p)();
    return 0;
}
int max(int x=5){cout<<x<<endl;return x;}

这样就没有问题了!注意要看清楚问题!


第二个问题:
转型函数多少个没关系,怎么定义也没关系。你的错误只要在于你调用的地方
不信你把函数调用注释了,绝对不会出现问题:
程序代码:
#include<iostream>
using namespace std;
class T{
private:
    int a;
    double b;
public:
    T(int a,double b):a(a),b(b){}
    operator double(){return b;}
    operator int(){return a;}//&Otilde;&acirc;&ETH;&ETH;&Egrave;&ccedil;&sup1;&ucirc;×&cent;&Ecirc;&Iacute;&micro;&ocirc;±à&Ograve;&euml;&Iacute;¨&sup1;&yacute;&pound;&not;&frac12;á&sup1;&ucirc;&Otilde;&yacute;&Egrave;·
};
int main(){
    T x(3,7.37);
  //  cout<<(2.1+x)<<endl;
    return 0;
}



因此你的问题不在转型函数:
另外你所说的参数是什么都无所谓,因为你的转型函数就没哟参数(这是不太合理的说法),当然,当我们调用的时候其实他的参数就相当于构造函数的参数
参数都一样,你还争论什么参数是int和double呢

转型一般都是隐式就行的也就是需要的时候执行,(可以通过explicit关键字禁止这种隐式转型,因为有时候它会带来麻烦)
所以主要区别你的转型函数在你的要转的那个结果的类型,笼统而且不负责任的说是返回值类型;
看下面这个例子:
程序代码:
#include<iostream>
using namespace std;
class T{
private:
    int a;
    double b;
public:
    T(int a,double b):a(a),b(b){}
    operator double(){return b;}
    operator int(){return a;}//&Otilde;&acirc;&ETH;&ETH;&Egrave;&ccedil;&sup1;&ucirc;×&cent;&Ecirc;&Iacute;&micro;&ocirc;±à&Ograve;&euml;&Iacute;¨&sup1;&yacute;&pound;&not;&frac12;á&sup1;&ucirc;&Otilde;&yacute;&Egrave;·
};
int main(){
    T x(3,7.37);

    int a = x;
    double b = x;

    cout << a << endl << b << endl;

  //  cout<<(2.1+x)<<endl;
    return 0;
}


这样你应该明白了吧,另外你的那个结果之所以错,是不是因为转型函数的问题
你那明显的错误,因为类的类型是你自己定义的,而且double是系统的,系统不可能事先知道你要给他们做加法
因此。你没有重载运算法,因此一个double类型的加上一个类是明显中的错误

哥们突然发现,你的这个错误太明显了,也太幼稚 了


#9
lj1201222012-11-27 16:53
佩服加膜拜!
#10
lyj1232012-11-27 18:37
回复 8楼 liufashuai
编译通不过

[ 本帖最后由 lyj123 于 2012-12-1 14:21 编辑 ]
#11
lz10919149992012-11-27 19:43
回复 8楼 liufashuai
第一个问题:
默认参数只允许在函数参数中使用,由编译器来帮你传递,而对于声明函数指针时的参数列表中是不能有默认参数的,调用的时候也必须传递所有参数。
你那段代码在gcc下编译是通不过的,当然我不知道你用的是什么编译器。
第二个问题:
程序代码:
#include<iostream>
using namespace std;

class X {
public:
    X(double d) : value(d) {}
    operator double() { return value; }
private:
    double value;
};

int main()
{
    X x(1.0);
    cout << (1.0 + x) << endl;
}
如果按照你的说法,cout << (1.0 + x) << endl; 这句肯定是编译不能过的,但是在gcc4.40下却通过了,并且输出了2。
这里存在这一个隐式的转换,因为X有一个到double的类型转换函数,1.0 + x的时候,编译器就会先把x转换成double来参加运算。
如果你定义了两个基本类型的转换,那么编译器就不知道应该调用哪个转换,因为两种类型都可以隐式转换后来参加运算。就象newdos说的那样产生了二义性。

所以呢你还只是个需要加强基础的新手,不要随便否定别人的看法,更不要说别人幼稚,因为幼稚的人是你。

#12
lyj1232012-12-01 14:19
回复 11楼 lz1091914999
这台联网的机子上没有装MinGw GCC/G++,我还没测试过他说的代码,现在才明白。
不过,出现 1.0+x的时候,编译器看见一个double,一个用户自定义类,不是去寻找类型转换函数吗,为什么不(隐式)调用double转换函数而会分不清调用哪个转换函数呢?
1