| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 433 人关注过本帖
标题:求助:有关复制构造函数与赋值
只看楼主 加入收藏
cb0212
Rank: 1
等 级:新手上路
帖 子:4
专家分:0
注 册:2012-2-20
结帖率:0
收藏
已结贴  问题点数:20 回复次数:8 
求助:有关复制构造函数与赋值
#include <iostream>
using namespace std;

class X {
public:
    X() { cout << "X()" << endl; }
    X(int i):a(i)
    {
        cout << "X(int)" << endl;
     }
    X( const X& x)
    {
        cout << "X(const X&)" << endl;
        a=x.a;
    }
    X& operator=(const X& x)
    {
        cout << "X& operator=(const X&)" << endl;
        a=x.a;
        return *this;
    }
private:
int a;
};

void main()
{
    X x1; // Constructor: X()
    X x2(1); // Constructor: X(int)
    X x3(x1); // Copy-constructor: X(const X&)
    X x4=x1; // Copy-constructor: X(const X&)
    x4 = x1;// Assign operator: X& operator=(const X&)
}
为什么倒数第二行调用的是X(const X&),而不是X& operator=(const X&)?


搜索更多相关主题的帖子: class public include private 
2012-03-08 14:05
lz1091914999
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:四川
等 级:贵宾
威 望:37
帖 子:2011
专家分:5959
注 册:2010-11-1
收藏
得分:7 
因为x4处于定义阶段,所以X a(b);和X a = b;是一样的,为了避免混淆,可以一直用X a(b);这样就比较清晰。

My life is brilliant
2012-03-08 14:16
cb0212
Rank: 1
等 级:新手上路
帖 子:4
专家分:0
注 册:2012-2-20
收藏
得分:0 
回复 2楼 lz1091914999
但是我把复制构造函数显示化:
explicit X( const X& x)
    {
        cout << "X(const X&)" << endl;
        a=x.a;
    }
那倒数第二行的就会编译错误,说明你上面说的那两个还是不一样的啊!能说下X x4=x1;到底是怎么个流程的不?
2012-03-08 14:34
BianChengNan
Rank: 8Rank: 8
等 级:贵宾
威 望:13
帖 子:302
专家分:972
注 册:2011-11-30
收藏
得分:7 
以下是引用cb0212在2012-3-8 14:34:29的发言:

但是我把复制构造函数显示化:
explicit X( const X& x)
    {
        cout << "X(const X&)" << endl;
        a=x.a;
    }
那倒数第二行的就会编译错误,说明你上面说的那两个还是不一样的啊!能说下X x4=x1;到底是怎么个流程的不?
这个问题就是按二楼说的,具体的要看汇编代码,至于你说的这个我也不清楚,需要运行下代码
刚才运行了一下,根据提示,我想应该是explicit 的问题,他的意思是只有这种形式才可以,也就是说X x4 = x1这句话,还是会掉拷贝构造函数,但是因为拷贝构造函数被声明为explicit ,所以拷贝构造函数的形式只能是X( const X& x) 这种形式的,故编译失败,其实你把构造函数声明为explicit,也有类似的效果,说得不对的地方请指教,多交流


[ 本帖最后由 BianChengNan 于 2012-3-8 16:32 编辑 ]

我的群:149544757 C/C++/Assembly 喜欢交流的朋友进,进群请写消息
2012-03-08 16:11
BianChengNan
Rank: 8Rank: 8
等 级:贵宾
威 望:13
帖 子:302
专家分:972
注 册:2011-11-30
收藏
得分:0 
以下是引用lz1091914999在2012-3-8 14:16:46的发言:

因为x4处于定义阶段,所以X a(b);和X a = b;是一样的,为了避免混淆,可以一直用X a(b);这样就比较清晰。
顶,能否请兄弟指教下库编译的问题,我会新开一贴说这个问题,如果兄弟看见了,一定要指教一二。多谢了

我的群:149544757 C/C++/Assembly 喜欢交流的朋友进,进群请写消息
2012-03-08 16:33
非死亡!
Rank: 8Rank: 8
来 自:四川
等 级:蝙蝠侠
帖 子:179
专家分:760
注 册:2011-10-31
收藏
得分:7 
这个问题  以下为个人意见:  
分析:一开始没有加explicit,能运行,加了后(X x4=x1;)这句出错.看来问题是这句了.那出错再那里呢?我百度了一下,发现有人说这是显示类型转换,于是想,这句(X x4=x1;)会不会也是有隐身的类型转换呢?二楼的兄台说:这句(X x4=x1;)和(x x4(x1))是一样的.那么怎么会一样呢?又因为是编译不了,那就是编译器自己编译时会把这句改动了.看网上说,隐式的转换会产生临时的对象.于是.........

结论:编译器在编译这句时(X x4=x1;),分成这2步进行:X temp(x1); X x4(temp); 这期间有个隐式临时的对象产生,由于加了explicit,不能隐式转化了.故x4初始化不了.编译出错.所以X x4=x1;与X x4(x1)是不同的.'='在编译阶段会有隐式转化.

论证:
程序代码:
#include <iostream>
using namespace std;

class X {
public:
    X() { cout << "X()" << endl; }
   explicit X(int i):a(i)
     {
        cout << "X(int)" << endl;
     }

private:
int a;
}; 

void main()
{
    X x1;
    X X2(1);      //这句编译通过.
    X x2 = 1;     //这句编译通不过.
 
}

能力 技巧
2012-03-08 17:43
lz1091914999
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:四川
等 级:贵宾
威 望:37
帖 子:2011
专家分:5959
注 册:2010-11-1
收藏
得分:0 
这有一段代码:
程序代码:
class A {};

class B {
public:
    B(const A&) {}
};

void f(B) {}

int main() {
    A a;
    f(a);
}

f(a);当编译器看到这段代码时,发现f接收一个B类型的参数,但是只给出了一个A类型的参数,所以编译器会到B中去查找接收A类型的构造函数,以便转换为B类型,使函数调用正常,这里编译发现了B(const A&),所以编译通过。
程序代码:
class A {};

class B {
public:
    explicit B(const A&) {}
};

void f(B) {}

int main() {
    A a;
    //! f(a); // 编译出错,编译器在查找接收A的构造函数时,会忽略前有explicit声明的构造函数。
    f(B(a));  // OK,自己动手,丰衣足食。
}
但是在B(const A&)之前加上explicit声明之后,情况就不一样了,f(a);编译器在B中查找接收A类型的构造函数时会忽略前有explicit声明的构造函数,所以这里编译出错,因为能够接收A类型并且前面没有explicit声明的构造函数并不存在。但是可以显示的调用这个构造函数,所以f(B(a));编译通过。
程序代码:
class X {
public:
    explicit X(const X&) {}
};

int main() {
    X x1;
    //! X x2 = x1; // 到X里去查找能够接收X类型的构造函数并且前面没有explicit声明,没找到,编译出错。
    X x3(x1);      // OK,自己动手,丰衣足食。
}
我想这个应该与上面的代码一样吧!



[ 本帖最后由 lz1091914999 于 2012-3-8 20:31 编辑 ]

My life is brilliant
2012-03-08 20:27
lz1091914999
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:四川
等 级:贵宾
威 望:37
帖 子:2011
专家分:5959
注 册:2010-11-1
收藏
得分:0 
以下是引用cb0212在2012-3-8 14:34:29的发言:

但是我把复制构造函数显示化:
explicit X( const X& x)
    {
        cout << "X(const X&)" << endl;
        a=x.a;
    }
那倒数第二行的就会编译错误,说明你上面说的那两个还是不一样的啊!能说下X x4=x1;到底是怎么个流程的不?
参数转换是C++中比较难理解的地方,我之所以简单的这样回答是希望你更容易理解,加上explicit不是什么显示化,这只是在执行参数转换的时候忽略掉这个构造函数而已。

My life is brilliant
2012-03-08 20:35
lz1091914999
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:四川
等 级:贵宾
威 望:37
帖 子:2011
专家分:5959
注 册:2010-11-1
收藏
得分:0 
以下是引用非死亡!在2012-3-8 17:43:35的发言:

这个问题  以下为个人意见:  
分析:一开始没有加explicit,能运行,加了后(X x4=x1;)这句出错.看来问题是这句了.那出错再那里呢?我百度了一下,发现有人说这是显示类型转换,于是想,这句(X x4=x1;)会不会也是有隐身的类型转换呢?二楼的兄台说:这句(X x4=x1;)和(x x4(x1))是一样的.那么怎么会一样呢?又因为是编译不了,那就是编译器自己编译时会把这句改动了.看网上说,隐式的转换会产生临时的对象.于是.........

结论:编译器在编译这句时(X x4=x1;),分成这2步进行:X temp(x1); X x4(temp); 这期间有个隐式临时的对象产生,由于加了explicit,不能隐式转化了.故x4初始化不了.编译出错.所以X x4=x1;与X x4(x1)是不同的.'='在编译阶段会有隐式转化.

论证:#include  
using namespace std;
 
class X {
public:
    X() { cout << "X()" << endl; }
   explicit X(int i):a(i)
     {
        cout << "X(int)" << endl;
     }
 
private:
int a;
};  
 
void main()
{
    X x1;
    X X2(1);      //这句编译通过.
    X x2 = 1;     //这句编译通不过.
  
}
隐式转换只会在类型不同时才会出现,但是这理参数类型一样,转换无疑是损失效率。

My life is brilliant
2012-03-08 20:39
快速回复:求助:有关复制构造函数与赋值
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.019298 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved