c ++构造函数和初始化程序行为。这5个代码之间有什么区别?

时间:2017-03-22 13:38:17

标签: c++ class constructor initializer

我是c ++编程语言的新手。我编写了几种代码模式来理解c ++构造函数和初始化程序。但我无法找出为什么一个构建失败而另一个构建失败。从我看来,似乎没有一个失败,另一个失败。代码是以下5个代码。代码示例1-2,2-3,3-4,4-5之间有什么区别。为什么一个失败但另一个失败?

Additional Info: 我正在用Xcode 8.2构建这些代码。

守则

示例1:

class A{
public:
  A(int xxx) { }
};

int main(){
  A a; // Fail here. I see this is because there is no default constructor in definition of class A.
}

示例2:

class A{
public:
  A(int xxx) { }
};

class B{
public:
  A a; // No fail. Why? I supposed it will fail like Example 1.
};

int main(){

}

示例3:

class A{
public:
  A(int xxx) { }
};

class B{
public:
  A a;           // No fail here.
  B(int xxx) { } // But fail here. Why? I just added constructor to Example 2.
};

int main(){

}

示例4:

class A{
public:
  A(int xxx) { }
};

class B{
public:
  A a;
  B(int xxx) : a(123) { } // No fail. Why Just adding ":a(123)" works.
};

int main(){

}

示例5:

class A{
public:
  A(int xxx) { }
};

class B{
public:
  A a;
  B(int xxx){ a = 123; } // Fail again. Why? I think ":a(123)" and "a=123" is same meaning.
};

int main(){

}

3 个答案:

答案 0 :(得分:4)

示例2没有错误,因为您从未尝试构建B。如果您添加到主B b;,则会收到类似

的错误
  

错误:使用已删除的函数'B :: B()'

在尝试实例化B之前没有收到错误的原因是因为A a;只是一个成员声明。直到构造函数被调用并且您尝试实例化a时才会发现它不是默认构造的。

示例3基本相同。现在您正在定义构造函数,编译器将自动向其添加a的默认初始化,因为您没有在成员初始化列表中提供一个。{1}}。当它这样做时,它看到A不是默认构造的,因此它会发出错误。

示例4没有失败,因为您指定了如何构造a。由于您这样做,编译器不会尝试默认构造它,而是使用您提供的值构造a

示例5因为与示例3中的原因相同而再次失败。它尝试向成员初始化列表添加默认初始化但不能,因为它不存在,这会给您带来错误。

答案 1 :(得分:2)

你似乎已经掌握了大部分内容,所以让我仔细研究一下并澄清一下。

示例1:您正在尝试创建A的实例而不提供所需的构造函数参数。

示例2:无法实例化类B,因为它需要创建A的实例,并且您尚未指定要将哪些参数发送到其构造函数。如果要在某处创建B的实例,则会在此处收到编译器错误。例如,将B b;放在main()。

示例3:构造函数B::B(int)无法编译,因为您没有为B::aA的实例)的构造函数指定有效参数。你在这里得到错误,因为在这个构造函数中你必须指定``的参数。

示例4:您在B::B的初始化列表中指定应将哪些参数传递给B::a。这是你需要做的就是编译它。

示例5:您在这里尝试分配123的值。这是在构造函数B::B的主体中完成的,在B的所有成员都已初始化之后调用。它没有为a的构造函数指定参数。它只是在它已经构建之后尝试为它分配一个新值。由于您没有指定应该发送到a的构造函数的值,因此会出现与示例3中相同的错误。

答案 2 :(得分:0)

  • 1 vs 2:示例2不会失败,因为您从未在主
  • 中实例化subprojects { apply plugin: 'java' repositories { // define repos for all projects } } configure(subprojects.findAll {it.name != 'core'}) { dependencies { // Add dependency on core for sub1 and sub2 compile project(':core') } } project(':sub1') { // define anything you want (e.g. dependencies) just for this subproject // alternative: use build.gradle in subproject folder } o B
  • 2 vs 3:示例3失败,因为在A的构造函数中,您没有调用BA::A()没有默认构造函数
  • 3 vs 4:示例4不会因为您在A构造函数中调用A::A()而失败。
  • 4 vs 5:示例5失败,因为(再次)您没有调用BA::A()没有默认构造函数。但A可以归为123(因为声明了隐式声明的复制赋值运算符,并且您有一个构造函数可以从{A构建A {1}})