如何调用适当的构造函数

时间:2019-05-24 05:52:10

标签: c++ c++11 visual-c++

为什么我不能为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";
  }
}

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

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;
}

当我尝试在容器中设置Geometry对象时,即使我已经给出了要调用的构造函数2的所有参数,也会调用构造函数1。

geometry(0.3, 32, 0.0, 0.0, "SPHERE", true);
Container cont("Sphere", "SPHERE", geometry);

3 个答案:

答案 0 :(得分: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     

在这里,Geometry的构造函数实际上称为{em> {}的构造函数。但是几何构造函数3和1也被称为...为什么?

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

Container

要覆盖默认行为,请显式使用member initialisation

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&)  
}

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

Demo


在切换到成员初始化时,您可能已经注意到构造函数3被调用了两次。同样,这是由于Container的构造函数使用其Container::Container(std::string strName, std::string strType, Geometry geometry) : stdstrContainerName(strName) , stdstrPluginType(strType) , Geom(geometry) // copy-constructor, i.e. Geometry(Geometry const&) { } 参数按值,通过复制构造创建了一个新对象。为了防止制作副本并使构造函数更有效,我们可以通过引用传递geometry。另外,我们可以对参数进行常量化,以确保不会在构造函数中修改引用。

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

Container

答案 1 :(得分:2)

Container的构造函数:

Container::Container(std::string strName, std::string strType, Geometry geometry)
{
    stdstrContainerName = stdstrContainerName;
    stdstrPluginType = stdstrPluginType;
    Geom = geometry;
}

没有Geom字段的任何显式初始化。它首先被默认初始化,因此被默认构造函数调用,然后为它分配geometry参数。

要实现所需的功能,您需要通过以下方式定义Container的构造函数:

Container::Container(std::string strName, std::string strType, Geometry geometry)
: Geom(geometry)
{
    stdstrContainerName = strName;
    stdstrPluginType = strType;
}

注意: Geom(geometry)部分。在这里调用Geom的构造函数,如果您没有在构造函数中放入类似的内容,则会调用默认的构造函数。

此外,我几乎可以肯定您的构造函数中存在错误。它可能应该是stdstrContainerName = strName;而不是stdstrContainerName = stdstrContainerName;stdstrPluginType也是如此。

还有一件事,这不是错误,并且在技术上是正确的,但是传递诸如std::stringGeometry之类的对象(即可能是“沉重”的对象)可能会降低性能,所以为什么您不通过引用吗?但这不是错误(至少不在您发布的代码中),并且与您的问题没有直接关系。

答案 2 :(得分:1)

通过值传递给Geometry geometry的构造函数的Container参数调用构造函数#1。因为您要按值传递它,所以将在Container的构造函数的堆栈上重新创建它。将其更改为const Geometry& geometry