谁能解释一下这题,关于operator new的

luofuwen1004 2014-10-09 10:15:05
#include <iostream>
using namespace std;
struct S
{
void * operator new(size_t size, void* p, int i)
{
((S*)p)->i = i;
return p;
}
int i;
};
S ss;
S* pss = new(&ss, 10)S();

int main()
{
cout<<ss.i<<" "<<pss->i<<endl;
S* pss2 = new(&ss,20)S;
cout<<ss.i<<" "<<pss2->i<<endl;
getchar();
return 0;
}

这题为什么会这么输出呢?
...全文
332 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
luofuwen1004 2014-10-12
  • 打赏
  • 举报
回复
引用 19 楼 sctianhu 的回复:
看这个 http://technet.microsoft.com/zh-cn/library/wewb47ee(v=VS.85).aspx 里面有示范代码,然后注意注释 ,如下! // by assigning the value 0 to pS->i.
膜拜大神哪
sctianhu 2014-10-11
  • 打赏
  • 举报
回复
看这个 http://technet.microsoft.com/zh-cn/library/wewb47ee(v=VS.85).aspx 里面有示范代码,然后注意注释 ,如下! // by assigning the value 0 to pS->i.
luofuwen1004 2014-10-10
  • 打赏
  • 举报
回复
引用 16 楼 mujiok2003 的回复:
很多扯淡的呀。 S是一个POD类型。 new S()会对所有成员进行默认初始化, new S则不初始化。
终于找到正确答案了!非常感谢,同时也感谢所有回答我的朋友们!
mujiok2003 2014-10-10
  • 打赏
  • 举报
回复
重载的operator new的指针是申请空间, 不要多管闲事初始化成员。 初始化成员是构造函数的工作。
mujiok2003 2014-10-10
  • 打赏
  • 举报
回复
很多扯淡的呀。 S是一个POD类型。 new S()会对所有成员进行默认初始化, new S则不初始化。
Uron 2014-10-10
  • 打赏
  • 举报
回复
引用 10 楼 luofuwen1004 的回复:
[quote=引用 9 楼 cs290473786 的回复:]
[quote=引用 8 楼 luofuwen1004 的回复:]
[quote=引用 7 楼 cs290473786 的回复:]
[quote=引用 6 楼 luofuwen1004 的回复:]
[quote=引用 5 楼 cs290473786 的回复:]
1. 前者构造的是临时对象,S* pss = new(&ss, 10)S();执行时结果i编程了10,但是这句执行之后,临时空间被回收被变成0;
2. 后者是局部变量,还在作用域内。

为什么前者就是临时变量呢,传递的不是ss的指针吗?如果把()去掉,变成S* pss = new(&ss, 10)S;这时候就会输出10,10了[/quote]

引用 6 楼 luofuwen1004 的回复:
[quote=引用 5 楼 cs290473786 的回复:]
1. 前者构造的是临时对象,S* pss = new(&ss, 10)S();执行时结果i编程了10,但是这句执行之后,临时空间被回收被变成0;
2. 后者是局部变量,还在作用域内。

为什么前者就是临时变量呢,传递的不是ss的指针吗?如果把()去掉,变成S* pss = new(&ss, 10)S;这时候就会输出10,10了[/quote]
S()是一个匿名对象,只在当前语句有效。而new的操作是在ss的地址处构建一个对象,编译器肯定是没有拷贝一份到ss的地址处。当S* pss = new(&ss, 10)S()执行后,s()匿名对象内容清空,ss的地址处还是这无效区域的内容,也就是0了。[/quote]


那可以解释一下为什么给A类添加一个A(){}构造函数之后,前者就会输出10,10吗[/quote]
可以。如果加入了S类的构造函数,我告诉你,你在构造函数里面添加一个断点,你就会发现构造函数在语句S* pss = new(&ss, 10)S这行会进入两次。为什么呢?因为恰恰相反,这次不仅匿名变量进入一次,然后编译器还拷贝了一份到ss的地址处,共2此。明白?[/quote]


不好意思,事实是只进入一次.[/quote]
不同的编译器会有不同的优化策略。如果想要了解这些的话就得看编译原理之类的了。我们需要的是学会分析,不管是一次还是两次,我们需要学会看内存和调试。
fztfztfzt 2014-10-10
  • 打赏
  • 举报
回复
不写构造函数不是还有默认构造函数吗?
luofuwen1004 2014-10-09
  • 打赏
  • 举报
回复
引用 3 楼 passion_wu128 的回复:
[quote=引用 2 楼 luofuwen1004 的回复:] [quote=引用 1 楼 lovesmiles 的回复:] S* pss = new(&ss, 10)S(); 你想问什么问题?如果是问前面为什么输出0,0的话,问题出来这个默认的构造函数这里。
是的,为什么第一个输出会是0,0呢[/quote] 因为ss是全局变量,存放在pe文件的data节,没有显示初始化时会初始化为0。[/quote] 表示不太明白:1.pss和pss2的区别在哪里 2.ss是不是全局变量结果都一样
passion_wu128 2014-10-09
  • 打赏
  • 举报
回复
引用 2 楼 luofuwen1004 的回复:
[quote=引用 1 楼 lovesmiles 的回复:] S* pss = new(&ss, 10)S(); 你想问什么问题?如果是问前面为什么输出0,0的话,问题出来这个默认的构造函数这里。
是的,为什么第一个输出会是0,0呢[/quote] 因为ss是全局变量,存放在pe文件的data节,没有显示初始化时会初始化为0。
luofuwen1004 2014-10-09
  • 打赏
  • 举报
回复
引用 1 楼 lovesmiles 的回复:
S* pss = new(&ss, 10)S(); 你想问什么问题?如果是问前面为什么输出0,0的话,问题出来这个默认的构造函数这里。
是的,为什么第一个输出会是0,0呢
勤奋的小游侠 2014-10-09
  • 打赏
  • 举报
回复
S* pss = new(&ss, 10)S(); 你想问什么问题?如果是问前面为什么输出0,0的话,问题出来这个默认的构造函数这里。
luofuwen1004 2014-10-09
  • 打赏
  • 举报
回复
引用 12 楼 fztfztfzt 的回复:
用vc6.0编译输出是10 10 / 20 20 .........
我用vs2013的结果是 0 0/20 20 如果给类A添加一个构造函数才是 10 10/20 20
fztfztfzt 2014-10-09
  • 打赏
  • 举报
回复
用vc6.0编译输出是10 10 / 20 20 .........
阿呆_ 2014-10-09
  • 打赏
  • 举报
回复
引用 楼主 luofuwen1004 的回复:
#include <iostream>
using namespace std;
struct S
{
	void * operator new(size_t size, void* p, int i)
	{
		((S*)p)->i = i;
		return p;
	}
	int i;
};
S ss;
S* pss = new(&ss, 10)S();

int main()
{
	cout<<ss.i<<"  "<<pss->i<<endl;
	S* pss2 = new(&ss,20)S;
	cout<<ss.i<<"  "<<pss2->i<<endl;
	getchar();
	return 0;
}
这题为什么会这么输出呢?
有种编译器优化叫做global variable lazy initialization。在你第一次使用这个global变量前不会调用=右边的初始化表达式(尤其针对非常量表达式)。
luofuwen1004 2014-10-09
  • 打赏
  • 举报
回复
引用 9 楼 cs290473786 的回复:
[quote=引用 8 楼 luofuwen1004 的回复:] [quote=引用 7 楼 cs290473786 的回复:] [quote=引用 6 楼 luofuwen1004 的回复:] [quote=引用 5 楼 cs290473786 的回复:] 1. 前者构造的是临时对象,S* pss = new(&ss, 10)S();执行时结果i编程了10,但是这句执行之后,临时空间被回收被变成0; 2. 后者是局部变量,还在作用域内。
为什么前者就是临时变量呢,传递的不是ss的指针吗?如果把()去掉,变成S* pss = new(&ss, 10)S;这时候就会输出10,10了[/quote]
引用 6 楼 luofuwen1004 的回复:
[quote=引用 5 楼 cs290473786 的回复:] 1. 前者构造的是临时对象,S* pss = new(&ss, 10)S();执行时结果i编程了10,但是这句执行之后,临时空间被回收被变成0; 2. 后者是局部变量,还在作用域内。
为什么前者就是临时变量呢,传递的不是ss的指针吗?如果把()去掉,变成S* pss = new(&ss, 10)S;这时候就会输出10,10了[/quote] S()是一个匿名对象,只在当前语句有效。而new的操作是在ss的地址处构建一个对象,编译器肯定是没有拷贝一份到ss的地址处。当S* pss = new(&ss, 10)S()执行后,s()匿名对象内容清空,ss的地址处还是这无效区域的内容,也就是0了。[/quote] 那可以解释一下为什么给A类添加一个A(){}构造函数之后,前者就会输出10,10吗[/quote] 可以。如果加入了S类的构造函数,我告诉你,你在构造函数里面添加一个断点,你就会发现构造函数在语句S* pss = new(&ss, 10)S这行会进入两次。为什么呢?因为恰恰相反,这次不仅匿名变量进入一次,然后编译器还拷贝了一份到ss的地址处,共2此。明白?[/quote] 不好意思,事实是只进入一次.
Uron 2014-10-09
  • 打赏
  • 举报
回复
引用 8 楼 luofuwen1004 的回复:
[quote=引用 7 楼 cs290473786 的回复:] [quote=引用 6 楼 luofuwen1004 的回复:] [quote=引用 5 楼 cs290473786 的回复:] 1. 前者构造的是临时对象,S* pss = new(&ss, 10)S();执行时结果i编程了10,但是这句执行之后,临时空间被回收被变成0; 2. 后者是局部变量,还在作用域内。
为什么前者就是临时变量呢,传递的不是ss的指针吗?如果把()去掉,变成S* pss = new(&ss, 10)S;这时候就会输出10,10了[/quote]
引用 6 楼 luofuwen1004 的回复:
[quote=引用 5 楼 cs290473786 的回复:] 1. 前者构造的是临时对象,S* pss = new(&ss, 10)S();执行时结果i编程了10,但是这句执行之后,临时空间被回收被变成0; 2. 后者是局部变量,还在作用域内。
为什么前者就是临时变量呢,传递的不是ss的指针吗?如果把()去掉,变成S* pss = new(&ss, 10)S;这时候就会输出10,10了[/quote] S()是一个匿名对象,只在当前语句有效。而new的操作是在ss的地址处构建一个对象,编译器肯定是没有拷贝一份到ss的地址处。当S* pss = new(&ss, 10)S()执行后,s()匿名对象内容清空,ss的地址处还是这无效区域的内容,也就是0了。[/quote] 那可以解释一下为什么给A类添加一个A(){}构造函数之后,前者就会输出10,10吗[/quote] 可以。如果加入了S类的构造函数,我告诉你,你在构造函数里面添加一个断点,你就会发现构造函数在语句S* pss = new(&ss, 10)S这行会进入两次。为什么呢?因为恰恰相反,这次不仅匿名变量进入一次,然后编译器还拷贝了一份到ss的地址处,共2此。明白?
luofuwen1004 2014-10-09
  • 打赏
  • 举报
回复
引用 7 楼 cs290473786 的回复:
[quote=引用 6 楼 luofuwen1004 的回复:] [quote=引用 5 楼 cs290473786 的回复:] 1. 前者构造的是临时对象,S* pss = new(&ss, 10)S();执行时结果i编程了10,但是这句执行之后,临时空间被回收被变成0; 2. 后者是局部变量,还在作用域内。
为什么前者就是临时变量呢,传递的不是ss的指针吗?如果把()去掉,变成S* pss = new(&ss, 10)S;这时候就会输出10,10了[/quote]
引用 6 楼 luofuwen1004 的回复:
[quote=引用 5 楼 cs290473786 的回复:] 1. 前者构造的是临时对象,S* pss = new(&ss, 10)S();执行时结果i编程了10,但是这句执行之后,临时空间被回收被变成0; 2. 后者是局部变量,还在作用域内。
为什么前者就是临时变量呢,传递的不是ss的指针吗?如果把()去掉,变成S* pss = new(&ss, 10)S;这时候就会输出10,10了[/quote] S()是一个匿名对象,只在当前语句有效。而new的操作是在ss的地址处构建一个对象,编译器肯定是没有拷贝一份到ss的地址处。当S* pss = new(&ss, 10)S()执行后,s()匿名对象内容清空,ss的地址处还是这无效区域的内容,也就是0了。[/quote] 那可以解释一下为什么给A类添加一个A(){}构造函数之后,前者就会输出10,10吗
Uron 2014-10-09
  • 打赏
  • 举报
回复
引用 6 楼 luofuwen1004 的回复:
[quote=引用 5 楼 cs290473786 的回复:] 1. 前者构造的是临时对象,S* pss = new(&ss, 10)S();执行时结果i编程了10,但是这句执行之后,临时空间被回收被变成0; 2. 后者是局部变量,还在作用域内。
为什么前者就是临时变量呢,传递的不是ss的指针吗?如果把()去掉,变成S* pss = new(&ss, 10)S;这时候就会输出10,10了[/quote]
引用 6 楼 luofuwen1004 的回复:
[quote=引用 5 楼 cs290473786 的回复:] 1. 前者构造的是临时对象,S* pss = new(&ss, 10)S();执行时结果i编程了10,但是这句执行之后,临时空间被回收被变成0; 2. 后者是局部变量,还在作用域内。
为什么前者就是临时变量呢,传递的不是ss的指针吗?如果把()去掉,变成S* pss = new(&ss, 10)S;这时候就会输出10,10了[/quote] S()是一个匿名对象,只在当前语句有效。而new的操作是在ss的地址处构建一个对象,编译器肯定是没有拷贝一份到ss的地址处。当S* pss = new(&ss, 10)S()执行后,s()匿名对象内容清空,ss的地址处还是这无效区域的内容,也就是0了。
luofuwen1004 2014-10-09
  • 打赏
  • 举报
回复
引用 5 楼 cs290473786 的回复:
1. 前者构造的是临时对象,S* pss = new(&ss, 10)S();执行时结果i编程了10,但是这句执行之后,临时空间被回收被变成0; 2. 后者是局部变量,还在作用域内。
为什么前者就是临时变量呢,传递的不是ss的指针吗?如果把()去掉,变成S* pss = new(&ss, 10)S;这时候就会输出10,10了
Uron 2014-10-09
  • 打赏
  • 举报
回复
1. 前者构造的是临时对象,S* pss = new(&ss, 10)S();执行时结果i编程了10,但是这句执行之后,临时空间被回收被变成0; 2. 后者是局部变量,还在作用域内。

64,646

社区成员

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

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