2016-04-15 86 views
2

让我们有两段代码。每段代码都有两个类,这些类非常相似。唯一的区别是定义类B的构造函数。定义构造函数的两种不同方式

第一程序:

using namespace std; 

class A 
{ 
    public: 
     A(int x) : val(x) { cout << val << endl; } 
    private: 
     int val; 
}; 

class B 
{ 
    public: 
     B(int x) { instanceA(x); } 
    private: 
     A instanceA; 
}; 


int main() 
{ 
    B instanceB(5); 
} 

第二方案:

using namespace std; 

class A 
{ 
    public: 
     A(int x) : val(x) { cout << val << endl; } 
    private: 
     int val; 
}; 

class B 
{ 
    public: 
     B(int x) : instanceA(x) { } 
    private: 
     A instanceA; 
}; 


int main() 
{ 
    B instanceB(5); 
} 

B类的在第一节目中的构造被定义为:

B(int x) { instanceA(x) } 

B类的在构造第二个程序定义为:

B(int x) : instanceA(x) { } 

第一个代码不工作,第二个是工作 - 什么定义构造函数在全球在这种情况下,第一和第二种方式也不同?

EDIT:代替B(int x) { instanceA(x); }需要是B(int x) { instanceA = A(x) }

+0

'B(INT X){instanceA = A(X)}' - 这不同于上述 –

+0

@EdHeal固定,遗憾 – scarface

+0

使用的代码:VAL(X){ } – Exceptyon

回答

4

对于第二壳体(member initializer listinstanceA将由A::A(int)直接进行初始化。

对于第一种情况,instanceA将被初始化为A::A()(默认构造函数),首先,构造函数的主体将在稍后执行。由于A没有默认构造函数,因此失败。

初始化顺序

3)然后,非静态数据成员在类定义 声明的顺序初始化。
4)最后,在构造函数的主体中执行

而且instanceA(x);不会做你所期望的(即调用A::A(int)来初始化它),它会被解析为instanceA.operator()(x);并不会编译,因为它是不提供operator()

+2

一旦'A'有一个默认的构造函数,第一个程序将失败,因为'instanceA'不是一个可调用的对象。 –

+0

因此,首先,对象的属性由'member initializer list'初始化,然后执行'{}'中的代码。如果'member'没有在'member initializer list'中初始化(没有调用正确的构造函数),编译过程失败了吗? 编辑:你已经编辑帖子,你。有人解释说。 – scarface

+0

@lolofon是的。 “如果对象未在成员初始化列表中初始化(正确的构造函数未被调用),”,那么默认的ctor将首先被调用,并且在这种情况下失败,因为没有'A'的默认ctor。这是使用成员初始值设定项列表的常见情况。 – songyuanyao

1
instanceA(x); 

不是函数

相关问题