如何调用适当的构造函数

sho*_*mit 8 c++ visual-c++ c++11

为什么我不能为该Geometry对象调用适当的构造函数?

class Geometry {
private:
  float fRadius;
  int iSegments;
  float fWidth;
  float fLenght;
  std::string stdstrType;
  bool bValid;

public:
  Geometry() {
    // Set data Elements
    qDebug() << "Constructor 1 is called";
  }

  Geometry(float Radius, int Segments, float Width, float Length,
    std::string strType, bool bValue) {
    // Set data Elements
    qDebug() << "Constructor 2 is called";
  }

  Geometry(const Geometry & g) {
    // Set data Elements
    qDebug() << "Constructor 3 is called";
  }
}
Run Code Online (Sandbox Code Playgroud)

我将此类用作另一个类中的数据变量。

class Container {
private:
  std::string stdstrContainerName;
  std::string stdstrPluginType;
  Geometry Geom;

public:
  Container();
  Container(std::string, std::string, Geometry geometry);
};

Container::Container() {
  stdstrContainerName = "Group";
  stdstrPluginType = "Geometry";
}

Container::Container(std::string strName, std::string strType,
  Geometry geometry) {
  stdstrContainerName = stdstrContainerName;
  stdstrPluginType = stdstrPluginType;
  Geom = geometry;
}
Run Code Online (Sandbox Code Playgroud)

当我尝试Geometry在容器中设置一个对象时,即使已为构造函数2调用提供了所有参数,也将调用构造函数1。

geometry(0.3, 32, 0.0, 0.0, "SPHERE", true);
Container cont("Sphere", "SPHERE", geometry);
Run Code Online (Sandbox Code Playgroud)

Tre*_*edJ 9

关于您的用例,以下是每一行的内容:

Geometry geometry(0.3, 32, 0.0, 0.0, "SPHERE", true);    // Geometry constructor 2    
Container cont("Sphere", "SPHERE", geometry);            // Container constructor 2, Geometry constructors 3 & 1     
Run Code Online (Sandbox Code Playgroud)

在这里,for的构造函数Geometry实际上是的构造函数之外调用的Container。但是几何构造函数3和1也被称为...为什么?

为什么如此。由于的构造函数按值Container接受Geometry参数,geometry因此将复制传递的对象(因此,将调用复制构造函数)。接下来是Geometry构造函数1,也就是默认构造函数实际上是在的构造函数中调用的Container。然后,另一个隐式生成的特殊方法复制分配被称为:

Container::Container(std::string strName, std::string strType, Geometry geometry)
  /*: stdstrContainerName()
    , stdstrPluginType()
    , Geom()*/                    // default-constructors implicitly called as member-initialisation    
{
    stdstrContainerName = stdstrContainerName;
    stdstrPluginType = stdstrPluginType;
    Geom = geometry;              // copy-assignment, i.e. operator= (Geometry const&)  
}
Run Code Online (Sandbox Code Playgroud)

要覆盖默认行为,请显式使用成员初始化

Container::Container(std::string strName, std::string strType, Geometry geometry)
    : stdstrContainerName(strName)
    , stdstrPluginType(strType)
    , Geom(geometry)            // copy-constructor, i.e. Geometry(Geometry const&)    
{
}
Run Code Online (Sandbox Code Playgroud)

这将产生构造函数3,因为现在调用了复制构造函数。

演示版


切换到成员初始化时,您可能已经注意到构造函数3被调用了两次。同样,这是由于Container的构造geometry函数通过value接受其参数,并通过复制构造创建了一个新对象。为了防止制作副本并使构造函数更有效,我们可以geometry按引用传递。另外,我们可以对参数进行常量化,以确保不会在构造函数中修改引用。

因此,的构造函数Container可以更改为:

Container(const std::string &strName, const std::string &strType, const Geometry &geometry);    
Run Code Online (Sandbox Code Playgroud)