Chinaunix首页 | 论坛 | 博客
  • 博客访问: 326613
  • 博文数量: 26
  • 博客积分: 1128
  • 博客等级: 少尉
  • 技术积分: 313
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-04 13:39
文章分类

全部博文(26)

文章存档

2012年(2)

2011年(10)

2010年(14)

分类: C/C++

2010-10-04 19:04:50

最近我在学习C++,看到了复制构造函数这一块,遇到些问题,就是关于在返回对象时是否使用复制构造函数,


以 下是我的开始的问题,然后在 xiyoulinux的邮件组里提问了,学长们都很热心的解答,同时也发邮件给了老师,老师发给我一个C++ Standard 1998 的pdf...并说明了页数··让我自己学习,看英文原版的书籍,呵呵··是挺爽的,挺兴奋的···悲剧的是,很多专业术语不太懂··但大部分还是可以理 解的。。呵呵··


我的原问题是:

最近我在学习C++,看到了复制构造函数这一块,遇到些问题,想请教一下大 家,vc和vim中编写C++的一些区别,一下是源代码:我的困惑也在下面

#include
#include
using namespace std;

class mystring
{
    char     *s;

    public:
        mystring (char *str);    //普通构造函数声明
        mystring (const mystring &obj);  //自定义复制构造函数声明
        ~mystring ()
        {
            if (s)
                delete [] s;
            cout << "Freeing s\n";
        }
        void show ()
        {
            cout << s << "\n";
        }
};

mystring::mystring (char *str)
{
    s = new char[strlen(str) + 1];
    cout << "Normally constructor called\n";
    strcpy (s, str);
       
}

mystring::mystring (const mystring &obj)
{
    s = new char[strlen(obj.s) + 1];
    cout << "Copy constructor called \n";
    strcpy (s, obj.s);
}

mystring input ()
{
    char instr[80];

    cout << "Please input a string:";
    cin >> instr;

    mystring ob (instr);   //在此会调用普通构造函数
   
    return ob;             //在此会调用自定义复制构造函数
}

int main (void)
{
    mystring obj = input ();  //调用自定义复制构造函数

    obj.show ();

    return 0;
}

本 应该的运行结果是:
Please input a string : hello
Normal constructor called.
Copy constructor called.
Freeing s.
hello
Freeing s.
在vc中的运行结果确实 也是这样,但是在linux下,运行的结果却是没有调用复制构造函数:
Please input a string : hello
Normal constructor called.
hello
Freeing s.

我有些困惑,出现这样的结果是因为编译环境的 问题么?还是其他原因?
如果想让程序运行出预想的结果应该怎么做?

我的描述可能不太准确,因为刚刚开始学习的。。
谢谢大 家先。。


kermit 学长的解答(谢谢咯·)
 其实你这个问题的核心就在于input()的返回值有没有生成一个临时对象。如
果input() 返回值当作一个临时对象处理,那就是VC的做法,mystring obj =
input()就会调用复制构造函数。   而如果input()没有返回时没有使用临时对
象,而是把input()的返回直接“嵌入”到正在构造的obj中,那就不用调用复制构造
函 数,这正是GCC的做法。 很明显,后者效率更高,GCC做得更好!(i agree with u)

你可以参考一下C++标准(n1905)12.2 Temporary objects一节中的那个例子:

X a (1);
X b = f ( X (2));
a = f ( a );

尤 其注意这段话:
Also, a temporary might be used to hold the result of f(X(2)) before
copying it to b using X’s copy-constructor; alternatively, f()’s result
might be constructed in b.

这就是说,这两种做法都是C++标准所允许的。 需要注意的是,后者的实现会少构
造一个临时对象,因此效率更高。

BTW:再一次证明,VC和GCC不是一个档次的工具。

下面是C++ Standard 1998中的说明:

Whenever a temporary class object is copied using a copy constructor,and this object and the copy have the same cv-unqualified type, an implementation is permitted to treat the original and the copy as two different
ways of referring to the same object and not perform a copy at all,even if the class copy constructor or
destructor have side effects. For a function with a class return type,if the expression in the return statement
is the name of a local object, and the cv-unqualified type of the local object is the same as the function return type, an implementation is permitted to omit creating the temporary object to hold the function return value, even if the class copy constructor or destructor has side effects. In these cases, the object is destroyed at the later of times when the original and the copy would have been destroyed without the opti-mization.111) [Example:
class Thing {
public:
Thing();
~Thing();
Thing(const Thing&);
Thing operator=(const Thing&);
void fun();
};
Thing f() {
Thing t;
return t;
}
Thing t2 = f();
Here t does not need to be copied when returning from f. The return value of f may be constructed directly into the object t2. ]
//由此看来,这两种方式都是被标准允许的哦···
阅读(1236) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-10-04 19:14:24

o..got it .. 这里的CV分别是const 以及volatile的缩写。用const,volatile以及const volatile之一作修饰的变量被成为cv-qualified ,否则该变量是cv-unqualified

chinaunix网友2010-10-04 19:07:06

cv-unqualified type 是什么类型阿?