为什么会有这样的输出结果???

lwy123 2010-06-11 08:57:02

class A
{
public:
A()
{
cout <<"A()" << endl;
}
~A()
{
cout <<"~A()" << endl;
}
void operator()(int& k)
{
k++;
cout <<k << endl;

}
};

int main()
{
vector<int> a(3);
for_each(a.begin(),a.end(),A());
return 0;
}

输出为:
A()
1
1
1
~A()
~A()
~A()
~A()
...全文
145 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
耍宝王 2010-06-12
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 demon__hunter 的回复:]

_DEBUG_POINTER(_Func);
也是一个函数调用~~~
所以临时对象数量,看编译器的处理了~~~
[/Quote]
好像不是这个问题

#include <vector>
#include <iostream>
using namespace std;

//不是用编译器自带的for_each
template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f)
{
for ( ; first!=last; ++first ) f(*first);
cout << "for_each return" << endl;
return f;
}

class A
{
public:
A(){cout << "A()" << endl;}
// A(const A&){cout << "A(const A&)" << endl;}
~A(){cout << "~A()" << endl;}
void operator()(int& k)
{
k++;
cout <<k << endl;
}
};

int main()
{
vector<int> a(3);
for_each(a.begin(), a.end(), A());
return 0;
}

VC2008编译输出
A()
1
1
1
for_each return
~A()
~A()
~A()//有三个析构函数

解开被注解掉的复制构造函数A(const A&){cout << "A(const A&)" << endl;}后编译输出为
A()
1
1
1
for_each return
A(const A&)
~A()
~A()//两个析构函数

问题好像出在编译器合成的复制构造函数上

另一个试验和13楼yunyun1886358的结果相同——只要添加一个包含有自定义复制构造函数的类作为数据成员
#include <vector>
#include <iostream>
using namespace std;

template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f)
{
for ( ; first!=last; ++first ) f(*first);
cout << "for_each return" << endl;
return f;
}

class test
{
public:
test(){}
test(const test&){}//自定义的复制构造函数
};

class A
{
public:
A(){cout << "A()" << endl;}
// A(const A&){cout << "A(const A&)" << endl;}
~A(){cout << "~A()" << endl;}
void operator()(int& k)
{
k++;
cout <<k << endl;
}
private:
test t;
};

int main()
{
vector<int> a(3);
for_each(a.begin(), a.end(), A());
return 0;
}

则也会输出
A()
1
1
1
for_each return
~A()
~A()//两个析构函数
机智的呆呆 2010-06-11
  • 打赏
  • 举报
回复
_DEBUG_POINTER(_Func);
也是一个函数调用~~~
所以临时对象数量,看编译器的处理了~~~
yunyun1886358 2010-06-11
  • 打赏
  • 举报
回复
彻底崩溃了,运行楼主的程序:

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>

using namespace std;

class A
{
public:
A()
{
cout <<"A()" << endl;
}

~A()
{
cout <<"~A()" << endl;
}

void operator()(int& k)
{
k++;
cout <<k << endl;
}
};

int main()
{
vector<int> a(3);
for_each(a.begin(),a.end(),A());
return 0;
}

得到结果:
A()
1
1
1
~A()
~A()
~A()
~A()
请按任意键继续. . .

然后给A加一个成员:

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>

using namespace std;

class A
{
public:
A()
{
cout <<"A()" << endl;
}

~A()
{
cout <<"~A()" << endl;
}

void operator()(int& k)
{
k++;
cout <<k << endl;
}

private:
string str;

};

int main()
{
vector<int> a(3);
for_each(a.begin(),a.end(),A());
return 0;
}

得到结果:
A()
1
1
1
~A()
~A()
~A()
请按任意键继续. . .
机智的呆呆 2010-06-11
  • 打赏
  • 举报
回复
在C++中,下面三种对象需要调用拷贝构造函数:   
1) 一个对象以值传递的方式传入函数体;   
2) 一个对象以值传递的方式从函数返回;   
3) 一个对象需要通过另外一个对象进行初始化;
下面来分析,首先A()产生一个临时对象假设叫temp1,这个对象以传值的方式传入函数体调用拷贝构造函数产生另一个临时对象假设叫temp2,
下面是vc10自带for_each函数原型:

template<class _InIt,
class _Fn1> inline
_Fn1 for_each(_InIt _First, _InIt _Last, _Fn1 _Func)
{ // perform function for each element
_DEBUG_RANGE(_First, _Last);
_DEBUG_POINTER(_Func);
return (_For_each(_Unchecked(_First), _Unchecked(_Last), _Func));
}

它转而调用

template<class _InIt,
class _Fn1> inline
_Fn1 _For_each(_InIt _First, _InIt _Last, _Fn1 _Func)
{ // perform function for each element
for (; _First != _Last; ++_First)
_Func(*_First);
return (_Func);
}

所以传参过程中会有临时变temp3产生,return (_Func);时可能要有temp4产生,
return (_For_each(_Unchecked(_First), _Unchecked(_Last), _Func));时可能有
temp5产生,所以编译器对于上述某一环节进行了优化,就可能得到lz所说的结果~~
yunyun1886358 2010-06-11
  • 打赏
  • 举报
回复
运行了pgplay修改后的程序,在MSVS 2010中得到如下结果:
A() // 首先构造一个对象a
A(const A&) // 形参的拷贝构造对象b
1
1
1
A(const A&) // 返回值时的拷贝构造对象c
~A() = A(const A&) // 析构形参对象b
~A() = A() // 析构第一个构造的对象对象a
~A() = A(const A&) // 析构函数返回时构造的对象c
耍宝王 2010-06-11
  • 打赏
  • 举报
回复
LZ不说我还真没有注意
这是for_each的相关代码(VC2008和g++的相关代码都差不多)
template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f)
{
for ( ; first!=last; ++first ) f(*first);
return f;
}

从上面的代码来看,理论输出结果应该是
A() //为for_each(a.begin(),a.end(),A());中A()触发的构造函数
1
1
1
~A()//此处为上面A()后的析构
~A()//此处为for_each中最后return f;语句所触发的复制构造函数所生成的临时变量的析构
把LZ代码修改后,也得到了验证
#include <algorithm>
#include <string>
#include <vector>
#include <iostream>
using namespace std;

class A
{
public:
A():str("A()"){cout << "A()" << endl;}
A(const A&):str("A(const A&)"){cout << "A(const A&)" << endl;}
~A(){cout << "~A() = " << str << endl;}
void operator()(int& k)
{
k++;
cout <<k << endl;
}
private:
string str;
};

int main()
{
vector<int> a(3);
for_each(a.begin(), a.end(), A());
return 0;
}

输出为:
A()
1
1
1
A(const A&)
~A() = A()
~A() = A(const A&)

但是,奇怪的是,如果使用LZ的原始带直接编译
g++的结果为:
A()
1
1
1
~A()
~A()
和预计的一样

但是用VC2008和DMC编译时
结果却为:
A()
1
1
1
~A()
~A()
~A()

如果用VC2008和DMC编译修改后代码
结果同样是:
A()
1
1
1
A(const A&)
~A() = A()
~A() = A(const A&)
预计的结果

加上LZ给出的这个结果。。。晕了
l690837769 2010-06-11
  • 打赏
  • 举报
回复
vector<int> a(3);
for_each(a.begin(),a.end(),A());

a.begin() 返回一个迭代器,指向a的第一个元素。
a.end() 返回一个迭代器,指向a的最后一个元素的下一个位置。
for each()好像是STL里的,你去查查用法。
yunyun1886358 2010-06-11
  • 打赏
  • 举报
回复
A是一个函数对象,一般作为STL算法的参数使用。
这一行,for_each(a.begin(),a.end(),A()); ,迭代vector变量a中的每一个元素,每一次迭代将a中的元素作为参数传给方法:
void operator()(int& k)
{
k++;
cout <<k << endl;
}
a中的元素都初始化为0,所以k是0,输出1,所以程序运行完毕,a中的元素都变为1.
至于输出结果:
A() // 调用函数对象的构造函数
1 // k = 0, k++ = 1
1
1
~A() // 由析构函数调用了4次来看,构造了4个A对象。循环了3次,只调用了一次构造函数,是不是编译器优化?
~A()
~A()
~A()

z569362161 2010-06-11
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 lwy123 的回复:]
没人知道吗?
[/Quote]

虫子应该知道吧?你在等等!
lwy123 2010-06-11
  • 打赏
  • 举报
回复
没人知道吗?
lwy123 2010-06-11
  • 打赏
  • 举报
回复
这是今天去面试的一道题
ww884203 2010-06-11
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 lthyxy 的回复:]
C/C++ code

//玩人,还是玩代码?
[/Quote]
说得很对
z569362161 2010-06-11
  • 打赏
  • 举报
回复
输出没问题,

只是不明白你想要得到什么?
  • 打赏
  • 举报
回复
for_each(a.begin(),a.end(),A()); 函数要求最后一个参数是用户自定义的一个函数。。不懂A()什么意思。。
liutengfeigo 2010-06-11
  • 打赏
  • 举报
回复

//玩人,还是玩代码?

64,282

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧