为什么调用超载构造函数会导致默认构造函数的调用
Why does calling an overloaded constructor cause a call of the default constructor?
我的c 程序m总是比我预期的要多的构造函数。它应该创建一个边缘,然后通过超载边缘构造仪的字符串输入自动创建两个节点。
,但它首先调用节点对象的默认构造函数,然后调用过载的自定义构造函数。破坏者不会立即删除默认节点。这会导致我的程序错误。
问题是程序应计算对象的数量并分配与对象数量相关的适当ID。
编译器输出
Default-Constructor
Default-Constructor
Overload-Constructor
ID: 1 numInstances: 2
Destructor
Overload-Constructor
ID: 2 numInstances: 1
Destructor
Edge: -> Node_0002
Destructor
Destructor
Program ended with exit code: 0
这是一个摘要,供您查看最有可能导致错误的代码:
main.cpp
int main() {
Edge e1 = Edge("1", "2");
std::cout << "Edge: " << e1.toString() << endl;
return 0;
}
node.hpp
double Node::numInstances = 0;
Node::Node()
{
numInstances++;
cout << "Default-Constructor" << endl;
double idNumber = numInstances;
m_id = setUpIdString(idNumber);
}
Node::Node(string id)
{
double idNumber = getNumberFromString(id);
cout << "Overload-Constructor" << endl;
cout << "ID: " << idNumber << " numInstances: " << numInstances << endl;
if (idNumber > numInstances) {
numInstances++;
m_id = setUpIdString(idNumber);
}
}
Node::~Node()
{
numInstances--;
cout << "Destructor" << endl;
}
edge.cpp
Edge::Edge(string src, string dst)
{
m_srcNode = Node(src);
m_dstNode = Node(dst);
}
编辑:
node.hpp
class Node
{
public:
Node();
Node(string id);
~Node();
string getId();
private:
string m_id;
static double numInstances;
};
edge.hpp
class Edge
{
public:
Edge(Node& rSrc, Node& rDst);
Edge(string src, string dst);
string toString();
Node& getSrcNode();
Node& getDstNode();
private:
Node m_srcNode;
Node m_dstNode;
};
构造函数不像C 中的其他功能。构造函数的工作是初始化对象。为了确保对象以明智的方式初始化,所有成员对象(和基本对象)都需要初始化。*这发生在之前的>构造函数主体的开头,因此当您在构造体主体中时,一切都处于明智的状态。
要确保以您想要的方式发生这种情况,您可以使用 initializer list (请注意,该术语在初始化各种容器时也指其他内容;如果您在之前听过术语关于这一点,这不是我在这里讨论的内容)。函数签名后,您放了一个结肠,然后放一个班级的每个成员(按照班级中声明的顺序相同)以及如何初始化。例如,如果您有以下struct
struct A {
int i;
char c;
std::string s;
A();
};
您可以声明将构造函数定义为
A::A() : i{17}, c{'q'}, s{"Hello, mrb! Welcome to Stack Overflow"}
{
// Nothing to do in the body of the constructor
}
这样,A
对象的成员在函数开始之前将17
,'q'
和问候初始化为 ,并且没有其他任何其他方式初始化。
由于您不执行此操作,因此编译器会使用节点的默认构造函数。然后,您可以在构造函数主体内部创建其他节点,然后将它们分配给类中的节点。
m_srcNode = Node(src);
m_dstNode = Node(dst);
在这里,这两个对象首先是用默认构造函数构造的,然后用Node(src)
和Node(dst)
调用过载的构造。之后,拨打隐式定义的复制分配程序将临时对象分配给m_srcNode
和m_dstNode
。最后,临时对象被破坏了。
如果要避免额外的构造函数,则可以编写成员初始器列表:
Edge::Edge(string src, string dst) : m_srcNode(src), m_dstNode(dst) {}
- 获取从C++中同一类中的构造函数调用的方法返回的值
- 从具有按值捕获的 lambda 移动构造 std::函数时,移动构造函数调用两次
- 确保所有构造函数调用相同的函数 c++ 设计模式
- 减少复制构造函数调用
- 使用回调函数从构造函数调用虚拟/派生方法的替代方法?
- 在 Google 测试中,我可以从构造函数调用 GetParam() 吗?
- C++ - 从另一个类构造函数调用类构造函数
- 在C++中初始化带有和不使用构造函数调用的对象有什么区别
- 是否可以从移动构造函数调用默认构造函数?
- 在模板生成器模式中分解重复的构造函数调用
- std::atexit 从全局对象的构造函数调用时的排序
- 对构造函数调用的约束
- 编译器错过了无效的构造函数调用,并调用不存在的(或私有的)默认构造函数
- 用构造函数调用填充向量
- 创建指针时是否没有构造函数调用
- 使用 emplace_back 避免移动构造函数调用的最佳方法?
- C++ 抽象类构造函数调用
- 为什么函数参数将带有参数的构造函数调用
- 为什么比“构造函数”调用更多的“解构器”调用
- 将对象传递给函数并不是导致构造函数调用