LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1304|回复: 7

C++高手能不能解释一下?为什么这里vs.net可以编译通过,但gcc却不能?

[复制链接]
发表于 2008-12-22 10:57:46 | 显示全部楼层 |阅读模式
程序如下:

#include <iostream>
using namespace std;
class Test;
void fun1(Test t);
Test fun2();
class Test
{
        public:
                Test(int n = 1){val = n; cout << "con." << endl;}
                Test(const Test &t){val = t.val; cout << "copy con." << endl;}
                Test &operator= (Test &t)
                {
                        val = t.val;
                        cout << "Assignment." << endl;
                        return *this;
                }
                private:
                        int val;
};
int main()
{
        Test t1(1);
        Test t2 = t1;
        Test t3;
       
        t3 = t1;
        fun1(t2);
        t3 = fun2();
       
        return 0;
}
void fun1(Test t){}
Test fun2()
{
        Test t;
        return t;
}

gcc无法编译通过,错误如下:
main.cpp: In function 'int main()':
main.cpp:28: error: no match for 'operator=' in 't3 = fun2()()'
main.cpp:11: note: candidates are: Test& Test:perator=(Test&)

但vs.net可以编译通过,程序运行结果如下:

con.
copy con.
con.
Assignment.
copy con.
con.
copy con.
Assignment.

这是老师上课给的例子,语法上我实在是找不出任何错误,为什么GCC就是不能过!?
发表于 2008-12-22 11:32:27 | 显示全部楼层
linux下编译cpp程序应该用g++吧
回复 支持 反对

使用道具 举报

发表于 2008-12-22 12:19:26 | 显示全部楼层
operator=的参数不是应该const 引用吗?
你们老师拿出这样的例子,我觉得有点不负责任阿
回复 支持 反对

使用道具 举报

发表于 2008-12-22 12:40:14 | 显示全部楼层
楼上正解,下面的fun2返回的是一个右值。

不过老师的水平这里不好说,毕竟编程真有本事的话实在没有理由再在那里当老师。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-12-23 10:18:11 | 显示全部楼层
“operator=的参数不是应该const 引用吗?”
请问x11兄,这点在哪里有说明?在c++primer中说operator=的形参通常是const引用,但也可以是非const引用。
回复 支持 反对

使用道具 举报

发表于 2008-12-23 14:00:48 | 显示全部楼层
应该尽量用const啊,否则一个右值潜在有可能被更改,这符合逻辑么?
回复 支持 反对

使用道具 举报

发表于 2008-12-23 16:49:33 | 显示全部楼层
其实4楼才是正解
fun2返回的是rvalue,而你的赋值操作符要求的参数是lvalue

不过赋值操作符的参数一般都用const reference

另外我还试了
Test t4 = fun2(),在fun2里返回了一个val初始化为2的对象
结果发现t4.val也初始化为2,但是调用的不是拷贝构造,打印的是"con."
回复 支持 反对

使用道具 举报

发表于 2008-12-23 20:31:58 | 显示全部楼层
Post by x11;1928496
其实4楼才是正解
fun2返回的是rvalue,而你的赋值操作符要求的参数是lvalue

不过赋值操作符的参数一般都用const reference

另外我还试了
Test t4 = fun2(),在fun2里返回了一个val初始化为2的对象
结果发现t4.val也初始化为2,但是调用的不是拷贝构造,打印的是"con."

看gcc的帮助文档,找到这样一段
       -fno-elide-constructors
           The C++ standard allows an implementation to omit creating a tempo-
           rary which is only used to initialize another object of the same
           type.  Specifying this option disables that optimization, and
           forces G++ to call the copy constructor in all cases.

加上这个编译,就能看到拷贝构造函数的调用了

  1. [zhanglei@redhat9:/tmp]$ g++ -fno-elide-constructors test.cpp -o test
  2. [zhanglei@redhat9:/tmp]$ ./test
  3. con.
  4. copy con.
  5. copy con.
复制代码
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表