为什么我不能为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);
答案 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> {1>}的构造函数。但是几何构造函数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,因为现在调用了复制构造函数。
在切换到成员初始化时,您可能已经注意到构造函数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::string
或Geometry
之类的对象(即可能是“沉重”的对象)可能会降低性能,所以为什么您不通过引用吗?但这不是错误(至少不在您发布的代码中),并且与您的问题没有直接关系。
答案 2 :(得分:1)
通过值传递给Geometry geometry
的构造函数的Container
参数调用构造函数#1。因为您要按值传递它,所以将在Container
的构造函数的堆栈上重新创建它。将其更改为const Geometry& geometry
。