使用默认值

时间:2016-06-22 21:25:49

标签: c++ constructor const

我有两个班级AB。类型bclass的{​​{1}}是类B的常量成员;我想要做的是如果没有向A提供bclass对象,则使用默认值初始化类B。 像这样:

A

输出结果为:

#include <iostream>
#include <string>
#include <unistd.h>

using namespace std;

class B{
public:
  B(string Bs): Bstring(Bs){
    cout << "B constructor: " << Bstring << endl;
  }

  ~B(){
    cout << "B destructor: " << Bstring << endl;
  }

private:
  const string Bstring;
};

class A{
public:
  A(const B subb = B("mmmmm")): bclass(subb){
    cout << "A constructor." << endl;
  }

  ~A(){
    cout << "A destructor." << endl;
  }

private:
  const B bclass;
};

int main(void){
    A a;
    cout << "doing work..." << endl;
    sleep(2);
    return 0;
}

问题在于,当只需要一个时,我就构建了2个B类(?)! 不知何故,B构造函数只被调用一次,而析构函数被调用两次......发生了什么?!

编辑1:

在阅读了@WhiZTiM的(好)回复之后,我添加了接下来的两个更新......

下一个代码解释了何时调用第二个构造函数:

B constructor: mmmmm
A constructor.
B destructor: mmmmm
doing work...
A destructor.
B destructor: mmmmm

输出:

#include <iostream>
#include <string>
#include <unistd.h>

using namespace std;

class B{
public:
  B(string Bs): Bstring(Bs){
    cout << "B constructor: " << Bstring << endl;
  }
  B(const B& bobj): Bstring(bobj.Bstring + "(copy)"){
    cout << "B copy constructor: " << Bstring << endl;
  }

  ~B(){
    cout << "B destructor: " << Bstring << endl;
  }

private:
  const string Bstring;
};

class A{
public:
  A(const B& subb = B("mmmmm")): bobj(subb){
    cout << "A constructor." << endl;
  }

  ~A(){
    cout << "A destructor." << endl;
  }

private:
  const B bobj;
};

int main(void){
  A a;
  cout << "doing work..." << endl;
  sleep(2);
  return 0;
}

正如@WhiZTiM指出的那样,编译器省略了对B构造函数的第三次调用(谢谢!)。

编辑2: 因为我只想要1个B对象,最好的想法是使用指针。代码必须是:

B constructor: mmmmm
B copy constructor: mmmmm(copy)
A constructor.
B destructor: mmmmm
doing work...
A destructor.
B destructor: mmmmm(copy)

这是输出:

#include <iostream>
#include <string>
#include <unistd.h>

using namespace std;

class B{
public:
  B(const string Bs): Bstring(Bs){
    cout << "B constructor: " << Bstring << endl;
  }
  B(const B& bobj): Bstring(bobj.Bstring){
    cout << "copying an existing B object." << endl;
  }

  ~B(){
    cout << "B destructor: " << Bstring << endl;
  }

private:
  const string Bstring;
};

class A{
public:
  A(B* subb = new B("mmmmm")): objb(subb){
    cout << "A constructor." << endl;
  }

  ~A(){
    cout << "A destructor." << endl;
    delete objb;
  }

private:
  const B* const objb;
};

int main(void){
  A a1; // This will call the default B constructor.
  A a2(new B("ooooo"));// This is calling a non default B object constructor.
  cout << "doing work..." << endl;
  sleep(2); //I need more motivation...
  return 0;
}

非常感谢@WhiZTiM

1 个答案:

答案 0 :(得分:1)

  

问题在于,当只有一个时,我构建了2个B类(?)   需要!不知何故,B构造函数只被调用一次,而   析构函数被调用两次......发生了什么?!

没有魔法在继续。编译器生成隐式复制和移动构造函数。 要获得真实的图片,请实施您的

class A{
public:
  A(const B subb = B("mmmmm")): bclass(subb){
    cout << "A constructor." << endl;
  }

  ~A(){
    cout << "A destructor." << endl;
  }

private:
  const B bclass;
};

在构造函数中,使用单个参数构造函数创建B,然后将其分配给subb,然后将其复制到bclass ...所以实际上有3个实例{ {1}}已创建。

  • 第一个是用户定义的构造函数,这就是你看到输出的原因
  • 第二个是用于构造B 的移动构造函数 - 编译器生成的默认
  • 第三个是用于构造subb 的复制构造函数 - 编译器生成的默认

您可能已经看过2,因为编译器elided a call