构造函数调用另一个构造函数,能行吗?

woneedjob 2009-12-19 06:18:09
如题,代码如下:

include <iostream>
using namespace std;
class Test
{
public:
Test(int i){m_i = i;}
Test(){Test(m_i);}//程序进入这里按F10一直中断(咚咚响,此时,系统在执行何操作?1问题)
隔一段时间,弹出提示“stack OverFlow ”紧着弹出“Access Violation”为什么这样呢?2问题
void SetValue (int j)
{
m_i = j;
}
int GetValue()
{
return m_i;
}
private:
int m_i;
};
int main()
{

Test b;//设断点
b.SetValue(10);
int value = b.GetValue();
cout<<value<<endl;
return 0;
}
...全文
801 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
huangdi7922 2012-07-31
  • 打赏
  • 举报
回复
不行的,因为你调用另一个构造函数又创建了一个临时对象,返回后原来的类等于没有调用执行构造函数里面的代码
laoyhi 2011-09-13
  • 打赏
  • 举报
回复
C++不知道,但java是可以的,可用this复用另一个“类的构造函数”来初始化当前构造函数
baihacker 2009-12-19
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 woneedjob 的回复:]
引用 16 楼 baihacker 的回复:
杯具,,,结贴了...


呵呵呵。真很不好意思。我等了有点久,见没有人踩我,我很不情愿的结贴了。
很感谢你的回复,虽然我一下子看不懂你发的。
[/Quote]
我说的可能才是你真正想要的...
一个构造函数把构造责任委托给另一个构造函数...
woneedjob 2009-12-19
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 baihacker 的回复:]
杯具,,,结贴了...
[/Quote]

呵呵呵。真很不好意思。我等了有点久,见没有人踩我,我很不情愿的结贴了。
很感谢你的回复,虽然我一下子看不懂你发的。
baihacker 2009-12-19
  • 打赏
  • 举报
回复
杯具,,,结贴了...
baihacker 2009-12-19
  • 打赏
  • 举报
回复
那些调用的只是生成一个临时对象,实际意义不大...
楼主的意思应该是把构建责任委托给另一个构造函数,在C++0x可能会有...




下面内容引自
http://zh.wikipedia.org/zh-cn/C%2B%2B0x#.E7.89.A9.E4.BB.B6.E5.BB.BA.E6.A7.8B.E7.9A.84.E6.94.B9.E8.89.AF







对象建构的改良
在标准C++中,建构式不能调用其它的建构式;每个建构式必须自己初始化所有的成员或是调用一个共用的成员函数。基类的建构式不能够直接作为派生类的建构式;就算基类的建构式已经足够,每个衍伸的类仍必须实做自己的建构式。类中non-constant的数据成员不能够在声明的地方被初始化,它们只能在建构式中被初始化。 C++0x将会提供这些问题的解决方案。

C++0x允许建构式调用其他建构式,这种做法称作委托或转接(delegation)。 仅仅只需要加入少量的代码,就能让数个建构式之间达成功能复用(reuse)。 Java以及C#都有提供这种功能。C++0x 语法如下:

class SomeType {
int number;
string name;
SomeType( int i, string& s ) : number(i), name(s){}
public:
SomeType( ) : SomeType( 0, "invalid" ){}
SomeType( int i ) : SomeType( i, "guest" ){}
SomeType( string& s ) : SomeType( 1, s ){ PostInit(); }
};

C++03中,建构式运行退出代表对象建构完成; 而允许使用转接建构式的 C++0x 则是以"任何"一个建构式退出代表建构完成。 使用转接的建构式,函数本体中的代码将于被转接的建构式完成后继续运行(如上例的 PostInit())。 若基底类使用了转接建构式,则派生类的建构式会在"所有"基底类的建构式都完成后, 才会开始运行。

C++0x 允许派生类手动继承基底类的建构式, 编译器可以使用基底类的建构式完成派生类的建构。 而将基类的建构式带入派生类的动作, 无法选择性地部分带入, 要不就是继承基类全部的建构式,要不就是一个都不继承(不手动带入)。 此外,若牵涉到多重继承,从多个基底类继承而来的建构式不可以有相同的函数签名(signature)。 而派生类的新加入的建构式也不可以和继承而来的基底建构式有相同的函数签名,因为这相当于重复声明。

语法如下:

class BaseClass
{
public:
BaseClass(int iValue);
};

class DerivedClass : public BaseClass
{
public:
using BaseClass::BaseClass;
};
此语法等同于 DerivedClass 声明一个DerivedClass(int) 的建构式。 同时也因为 DerivedClass 有了一个继承而来的建构式,所以不会有默认建构式。

另一方面,C++0x可以使用以下的语法完成成员初始化:

class SomeClass
{
public:
SomeClass() {}
explicit SomeClass(int iNewValue) : iValue(iNewValue) {}

private:
int iValue = 5;
};
若是建构式中没有设置iValue的初始值,则会采用类定义中的成员初始化,令iValue初值为5。在上例中,无参数版本的建构式,iValue便采用默认所定义的值; 而带有一个整数参数的建构式则会以指定的值完成初始化。

成员初始化除了上例中的赋值形式(使用"=")外,也可以采用建构式以及统一形的初始化(uniform initialization,使用"{}")。
woneedjob 2009-12-19
  • 打赏
  • 举报
回复
哪请回答下下面这个问题好吗?

Test(){Test(m_i);}//这个调用的是自身
为什么?怎末会是自身呢,一个带参,一个没带参啊
woneedjob 2009-12-19
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 mstlq 的回复:]
再给楼主一个可行的……
C/C++ codeTest(){Test(this->m_i);}

直接的m_i可能被理解成地址了,于是调用了placement new……
[/Quote]
呵呵,可能?也就只能先这样理解了?
mstlq 2009-12-19
  • 打赏
  • 举报
回复
注:11楼纯属猜测……
mstlq 2009-12-19
  • 打赏
  • 举报
回复
再给楼主一个可行的……
Test(){Test(this->m_i);}


直接的m_i可能被理解成地址了,于是调用了placement new……
woneedjob 2009-12-19
  • 打赏
  • 举报
回复
Test(){Test(m_i);}//这个调用的是自身
为什么?怎末会是自身呢,一个带参,一个没带参啊

呵呵。分析不出来
woneedjob 2009-12-19
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 mstlq 的回复:]
可以……
C/C++ code
#include<iostream>usingnamespace std;class Test
{public:
Test(int i){m_i= i;}
Test(){Test((int)m_i);}//markvoid SetValue (int j)
{
m_i= j;
}int GetValue()
{return m_i;
}private:int m_i;
};int main()
{

Test b;//设断点 b.SetValue(10);int value= b.GetValue();
cout<<value<<endl;return0;
}
[/Quote]

Test(){Test((int)m_i);}//这里改了好像能达到目的了,请问为什么?m_i本身就是定义为int了啊,强制
转换来作什么用呢?
mstlq 2009-12-19
  • 打赏
  • 举报
回复
Test(){Test(m_i);}//这个调用的是自身
Test(){Test((int)m_i);}//这样才是调用另一个
Test(){Test(3);}//这样也是调用另一个
Test(){Test(GetValue());}//这样也是另一个

具体原因,请自行分析……
woneedjob 2009-12-19
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 mstlq 的回复:]
可以调用另一个构造函数……
但是不能调用本身,否则就是无穷递归
[/Quote]
现在调用的是另一个啊,帮忙运行分析了。
woneedjob 2009-12-19
  • 打赏
  • 举报
回复
这是面试题目。大概意思是问能不能给m_i正确赋值。
运行是出现上述问题,现在想请教出现问题的原因。从代码上分析。谢谢。、
kingstarer 2009-12-19
  • 打赏
  • 举报
回复
不行
详见
http://hi.baidu.com/%BB%CA%BC%D2%BE%C8%D0%C71985/blog/item/f4101deed62c42212df534e4.html
mstlq 2009-12-19
  • 打赏
  • 举报
回复
可以调用另一个构造函数……
但是不能调用本身,否则就是无穷递归
Julykey 2009-12-19
  • 打赏
  • 举报
回复
你的代码在VS2005下会出现如下警告: warning C4717: “Test::Test”: 如递归所有控件路径,函数将导致运行时堆栈溢出
mstlq 2009-12-19
  • 打赏
  • 举报
回复
可以……

#include <iostream>
using namespace std;
class Test
{
public:
Test(int i){m_i = i;}
Test(){Test((int)m_i);}//mark
void SetValue (int j)
{
m_i = j;
}
int GetValue()
{
return m_i;
}
private:
int m_i;
};
int main()
{

Test b;//设断点
b.SetValue(10);
int value = b.GetValue();
cout<<value<<endl;
return 0;
}
  • 打赏
  • 举报
回复
貌似不行吧,构造函数的意思就是在你构造对象的时候首先得调用构造函数来初始化该对象,而你在未初始化的构造函数中调用未初始化的函数,

64,655

社区成员

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

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