string a="123456";到底调用了几个构造函数?

c++primer上的意思是stringa="123456";等价于stringa(string("123456"));相当于调用了一个带一个参数的构造函数,再调用一个复... c++ primer上的意思是string a="123456";等价于string a(string("123456"));相当于调用了一个带一个参数的构造函数,再调用一个复制构造函数,可自己写如下代码
//myclass.h
#pragma once
class myClassA
{
private:
int a;
public:
myClassA(int);
myClassA(const myClassA&);
};
//myclass.cpp
#include "classA.h"
#include <iostream>
using namespace std;

myClassA::myClassA(const myClassA &tmp):a(tmp.a)
{
cout<<"copy constructor is called"<<endl;
}
myClassA::myClassA(int tmp):a(tmp)
{
cout<<"constractor with 1 para is called"<<endl;
}
//main.cpp
#include "classA.h"
int main()
{
myClassA temp=4;
}
实际打印出的是constractor with 1 para is called
复制构造函数并没有调用,仅相当于myClassA temp(4);而非myClassA temp(myClassA(4));
什么原因呢?
编译器优化了?用linux 的g++效果也是一样的,是C++ primer说的不对?还是现在的编译器变了?
无关operator=
即便我myClassA temp(myClassA (4));复制构造函数还是没有被调用。标准c++不能这样吧?
展开
 我来答
WM_THU
2013-08-06 · TA获得超过7165个赞
知道大有可为答主
回答量:4285
采纳率:80%
帮助的人:4088万
展开全部

myClassA temp=4;

这一句是在对象声明的时候就“赋值”,这时编译器会直接匹配最佳的类型转换构造函数(也就是单参数的构造函数),又右值的类型是int,正好与myClassA::myClassA(int)匹配成功。这个解释我记得是在C++ Primer Plus上看到的。

myClassA  temp(myClassA (4));
经实验,这句话只会调用int类型参数的构造函数。我们有理由认为是编译器优化了:因为中间构造的临时变量,到后来其实并不会存在,因此编译器没理由浪费一次复制操作。而且下面更进一步的实验更有力地证明了这个结论:


#include <iostream>
using namespace std;
//myclass.h
//#pragma once
class myClassA
{
public:
    int a;
    char b;

    myClassA(int);
    myClassA(const myClassA&);
};
//myclass.cpp
//#include "classA.h"


myClassA::myClassA(const myClassA &tmp):a(tmp.a)
{
    b = 'c';
    cout<<"copy constructor is called"<<endl;
}
myClassA::myClassA(int tmp):a(tmp)
{
    b = 'a';
    cout<<"constractor with 1 para is called"<<endl;
}
//main.cpp

int main()
{
    myClassA temp(myClassA(4));
    cout<<temp.b<<endl;
    return 0;
}
追问
myClassA temp1;
myClassA temp2(temp1=myClassA (4));
myClassA temp3(myClassA(4));
temp2与temp3是截然不同的。这样就更令人费解为什么myClassA temp3(myClassA(4))只翻译成myClassA temp3(4);
我的primer那本书是讲string a="1234";是会调用两个构造函数的
追答
  1. 关于为什么myClassA temp3(myClassA(4))只翻译成myClassA temp3(4);
    我在上面已经提出自己的猜想了。请仔细阅读。

  2. 至于书本不一样的问题,我也不知道为什么书会不一样。

bhtzu
2013-08-06 · TA获得超过1.1万个赞
知道大有可为答主
回答量:8088
采纳率:85%
帮助的人:4591万
展开全部
myClassA(const myClassA&);

注意你这个复制构造函数,用了地址引用,而代码中myClassA (4)是类名调用,并不产生一个实际的变量,如果你再声明一个myClassA temp2(temp);复制构造函数就生效了。
一般来说,对类进行operator=,应该重载运算符,如果不重载,会产生很多的不可预知性。书上说的,应该是具有运算符重载的类,默认的安全处理方式吧。
追问
我认为是这样的,myClassA (4)是产生了一个有内存地址的变量 ,但没有显式保存这个变量名而已,实际上编译器会这么翻译myClassA temp(myClassA (4));
myClassA tmp(4);//tmp为隐藏变量
temp(tmp);
从而调用复制构造函数。

int i=10;
const int & a=i+20;
这样是合法的i+20是有一个隐藏tmp保存的 a引用的是这个tmp
追答
WM_THU说的很有道理,就是在没有重载运算符的情况下匹配最佳构造函数。在具有运算符重载的类中,实现方式是由重载函数指定的,而在标准例程中,通常都是调用了复制构造函数。
所以你的例子应该说是特例,而值得研究的就是myClassA temp(myClassA (4));和myClassA temp2(temp);

这个我认为应该是编译器优化造成的两个表现不一致。
本回答被提问者采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
w1...r@163.com
2013-08-06
知道答主
回答量:6
采纳率:0%
帮助的人:8903
展开全部
class RString { 
 public: 
  RString (const char *str=NULL);   //构造函数    RString (const RString &);    //拷贝构造函数    ~RString (void);      //析构函数   
  RString& operator= (const RString &);  //重载"=",字符转赋值   
  RString  operator+ (const RString &other); //重载"+",字符串链接   
  RString  operato - (const RString &other); //重载"-",删除子串  
  RString& operator-= (const RString &other); //重载"-=",删除子串   
  RString& operator+= (const RString &other); //重载"+=",字符串链接    
  bool operator== (const RString &other);  //重载"==",判断两个字符串相等  

  bool operator< (const RString &other);  
  bool operator> (const RString &other);  
  friend ostream& operator<< (ostream &, const RString &); //重载<<,这里必须使用friend,因为涉及到两个类之间私有成员的访问    
  friend istream& operator>> (istream &,const RString &); //重载>>,              private: 
  char *rs_data; };用事实说话把

MSDNlibrary中说,string a="123456";其实是类的运算符重载。

追问
string a;
a="123456";
这样调用的是operator=函数,
string a="123456";和operator=无关,在这里调用的是构造函数
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
zhaozssu
2013-08-06
知道答主
回答量:23
采纳率:0%
帮助的人:10.6万
展开全部
个人感觉myClassA temp=4;这个只是初始化吧,你如果试试myClassA temp1 = 4; myClassA temp = temp1;最后结果就是调用带参数的构造函数和调用复制构造函数,myClassA temp = temp1;这句话是调用复制构造函数
试了半天,myClassA temp(myClassA (4));确实不调用复制构造函数啊,这句话的结果就相当于myClassA temp=4了
追问
问题就是为什么myClassA temp(myClassA (4));不调用复制构造函数呢?
追答
想通了吗?我也不清楚了~
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(2)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式