除了隐式默认构造函数外,编译器会不会合成其他的构造函数

pilipili 2008-05-25 02:16:03
两个问题:
1、除了隐式默认构造函数外,编译器会不会合成其他的构造函数,包括非隐式的默认构造函数,普通构造函数?
2、如果类有虚函数表,可以为这个类定义构造函数吗?
...全文
153 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
Peterry 2008-05-25
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 iwong 的回复:]
下面的代码反而会出错,因为A::A(int c)由于有默认参数,所以也能匹配A::A(),编译器不知道匹配哪一个A::A()

C/C++ codeclass A
{
int a;
int b;
public:
A() : a(0), b(1)
{
}
A(int c = 0)
: a(c)
, b(c+1)
{
}
};

void _tmain(int argc, _TCHAR* argv[])
{
A a;
}
[/Quote]

对,这个其实就是一个构造函数形式的问题,由于符合A()的形式有两个了,所以会产生ambigious
Peterry 2008-05-25
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 pilipili 的回复:]
(15楼)“至于有默认参数的构造函数可以通过,我想就是因为它符合我们使用时的形式A a”,恩,发现我又不自觉把问题想复杂了。

谢谢大家,准备结贴了。

Peterry 10

baihacker 10

积分不够,下次会多加点。
[/Quote]

谢谢了^_^,有了你这10分,我升二衩了呵呵
iwong 2008-05-25
  • 打赏
  • 举报
回复
下面的代码反而会出错,因为A::A(int c)由于有默认参数,所以也能匹配A::A(),编译器不知道匹配哪一个A::A()
class A
{
int a;
int b;
public:
A() : a(0), b(1)
{
}
A(int c = 0)
: a(c)
, b(c+1)
{
}
};

void _tmain(int argc, _TCHAR* argv[])
{
A a;
}
pilipili 2008-05-25
  • 打赏
  • 举报
回复
(15楼)“至于有默认参数的构造函数可以通过,我想就是因为它符合我们使用时的形式A a”,恩,发现我又不自觉把问题想复杂了。

谢谢大家,准备结贴了。

Peterry 10

baihacker 10

积分不够,下次会多加点。

Peterry 2008-05-25
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 iwong 的回复:]
引用 11 楼 Peterry 的回复:
我试过了

C/C++ code
class A{

};

class B{
A a;
};

int main(){
B b;
return 0;
}


编译通过了...


C/C++ codeclass A
{
int a;
int b;
public:
A(int c = 0)
: a(c)
, b(c+1)
{
}
};

void _tmain(int argc, _TCHAR* argv[])
{
A a;
}


这样照样能通过编译,嘿嘿。并不是说只要自定义了…
[/Quote]
至于有默认参数的构造函数可以通过,我想就是因为它符合我们使用时的形式A a;吧
就好象

class A{
public:
A(float i){

}
};

class B{

};

int main(){
A a(new B());
return 0;
}

是不行的一样吧
Peterry 2008-05-25
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 pilipili 的回复:]
class A
{
public:
A(int i)
{
m_i = i;
}
int m_i;
};
class B
{
A a;
};
int main()
{
B b;
return 0;
}

这样就不会了,error C2512: 'B' : no appropriate default constructor available。
[/Quote]

你的意思我明白了,这样的确是不能通过,因为A a;需要的构造函数是A();而我们只提供了A(int),我一开始把你的意思理解错了...
这样的确是必须要默认构造函数.其实这主要不是因为A类有可能有其他类的成员对象,我试了一下这个代码

class A{
A(int i){

}
};

int main(){
A a;
return 0;
}

一样也不能通过,这是因为我们没有提供一个合适形式的构造函数
iwong 2008-05-25
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 Peterry 的回复:]
我试过了

C/C++ code
class A{

};

class B{
A a;
};

int main(){
B b;
return 0;
}




编译通过了...
[/Quote]
class A
{
int a;
int b;
public:
A(int c = 0)
: a(c)
, b(c+1)
{
}
};

void _tmain(int argc, _TCHAR* argv[])
{
A a;
}

这样照样能通过编译,嘿嘿。并不是说只要自定义了构造函数,就必须再手工定义一个无参数构造函数(默认构造函数),默认参数的构造函数照样能起到无参数构造函数的作用,系统会自动匹配的。
pilipili 2008-05-25
  • 打赏
  • 举报
回复
class A
{
public:
A(int i)
{
m_i = i;
}
int m_i;
};
class B
{
A a;
};
int main()
{
B b;
return 0;
}

这样就不会了,error C2512: 'B' : no appropriate default constructor available。
Peterry 2008-05-25
  • 打赏
  • 举报
回复
我试过了

class A{

};

class B{
A a;
};

int main(){
B b;
return 0;
}


编译通过了...
pilipili 2008-05-25
  • 打赏
  • 举报
回复
第三个问题补充:

这里的“默认构造函数”指可以不使用参数来调用的任何构造函数。
“一定需要默认构造函数”意思是,如果没有某人构造函数,编译器会报错。“我想到的一种情况是,当这个类有可能成为其他类的member object时”,这是因为在对这个member object初始化时,找不到它的默认构造函数。

第一次提问,问题没讲清楚。呵呵。
matrixdwy 2008-05-25
  • 打赏
  • 举报
回复
还会构造一个复制构造函数
飞哥 2008-05-25
  • 打赏
  • 举报
回复

第三个问题是:什么时候一定需要默认构造函数?
1.你需要自己控制构造过程的时候
2.你自己定义了构造函数,并且还希望该对象可以无参构造时
baihacker 2008-05-25
  • 打赏
  • 举报
回复
第三个问题是:
什么时候一定需要默认构造函数?

我猜你是想问,在什么时候用户没有提供构造函数,而编译器合成的构造函数不是平凡的.
member object
base class
virtual function
virtual base
pilipili 2008-05-25
  • 打赏
  • 举报
回复
好,我想我知道答案了。

编译器会自动在 所有 的构造函数前加上一段代码,以完成调用父类的构造函数,提供vptr,设置虚函数表,初始化member object等功能,因此对这两个问题答案都是“是”,虚函数表不妨碍自定义构造函数,因为设置虚函数表的任务由编译器完成,会加到每个构造函数里。

第三个问题是:
什么时候一定需要默认构造函数?

我想到的一种情况是,当这个类有可能成为其他类的member object时。

不知道这样理解对不对。
飞哥 2008-05-25
  • 打赏
  • 举报
回复

1、除了隐式默认构造函数外,编译器会不会合成其他的构造函数,包括非隐式的默认构造函数,普通构造函数?
如果你自己不定义任何构造函数,编译器用到的就帮你提供个,只是可能会有问题。
2、如果类有虚函数表,可以为这个类定义构造函数吗?
为什么不可以呢?
Peterry 2008-05-25
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 pilipili 的回复:]
问题补充:

在网上看到这样一句话,“编译器在A的每个构造函数中都加入了一些代码,负责调用父类的构造函数,并且这些隐藏的代码是添加在 usre_code 前面”,问题中的“合成”实际上是指会不会在构造函数中加入这样类似的代码
[/Quote]

我想是会的,因为编译器所添加的这些代码是使构造函数能够完成自己的工作必须的,不论是什么构造函数,都应该有和默认构造函数相同的功能,即调用父类构造函数等等.
不确定,等高手解答.
baihacker 2008-05-25
  • 打赏
  • 举报
回复
1、除了隐式默认构造函数外,编译器会不会合成其他的构造函数,包括非隐式的默认构造函数,普通构造函数?

复制构造函数呢?

2、如果类有虚函数表,可以为这个类定义构造函数吗?

你可以相信编译器所做的工作是正确的,如果有虚函数,虚基类,有member object,有具有显示构造函数的base class...编译器可以调用相应的构造函数,让那些虚函数表指针等指向正确的地方.
pilipili 2008-05-25
  • 打赏
  • 举报
回复
问题补充:

在网上看到这样一句话,“编译器在A的每个构造函数中都加入了一些代码,负责调用父类的构造函数,并且这些隐藏的代码是添加在 usre_code 前面”,问题中的“合成”实际上是指会不会在构造函数中加入这样类似的代码
Peterry 2008-05-25
  • 打赏
  • 举报
回复
不太明白你的意思,按我的理解:
1.编译器自动添加的就是默认构造函数,ClassName(){}
2.为什么不可以呢

64,692

社区成员

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

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