c++ - 如何调用适当的构造函数

标签 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);

最佳答案

关于您的用例,这是每行调用的内容:

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 的构造函数实际上是在 Container 的构造函数之外调用的。但是几何构造函数 3 和 1 也被调用...为什么?

为什么确实如此。由于 Container 的构造函数按值采用 Geometry 参数,因此将复制传递的 geometry 对象(因此调用复制构造函数)。接下来,Geometry constructor 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&)  
}

要覆盖默认行为,请使用 member initialisation明确地:

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

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

Demo


在切换到成员初始化时,您可能已经注意到构造函数 3 被调用了两次。同样,这是由于 Container 的构造函数采用其geometry 参数按值,通过复制构造创建了一个新对象。为了防止复制并提高构造函数的效率,我们可以通过引用传递 geometry。此外,我们可以对参数进行常量化,以保证在构造函数中不修改引用。

因此Container的构造函数可以改成:

Container(const std::string &strName, const std::string &strType, const Geometry &geometry);    

关于c++ - 如何调用适当的构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56286563/

相关文章:

c++ - 运行时错误 :SIG SEGV

javascript - 使用 Google Protocol Buffer 在 C++ 和 JavaScript 端点之间序列化/反序列化数据?

C++11 如何观察 atomic::store 和 atomic::load 中的内存顺序

c++ - 嵌套在模板类中的模板类在 MSVC++ 中给出错误

c++ - 使用 _Ropen 打开物理文件时出错

C++限制模板模板中的内部类型

c++ - 不是 VS2017 中的编译时常量表达式

c++ - "no base classes of the same type as the first non-static data member"

c - #将_snprintf_s定义为snprintf

visual-c++ - 如何在Windows 8文本服务框架中找到光标位置?