C++ c++;子类和运算符=:无限循环和意外调用
下面的代码转到无限循环C++ c++;子类和运算符=:无限循环和意外调用,c++,inheritance,C++,Inheritance,下面的代码转到无限循环 #include <string> #include <iostream> using namespace std; class A{ public: A(){ cout << "Normal constructor" << endl; } A(const A& moo){ cout << "It's a constructo
#include <string>
#include <iostream>
using namespace std;
class A{
public:
A(){
cout << "Normal constructor" << endl;
}
A(const A& moo){
cout << "It's a constructor!" << endl;
operator=(moo);
}
void operator=(const A& moo){
cout << "Calling A::Operator=" << endl;
}
};
class B : public A{
public:
B(){}
B(const A& thea){
cout << "Gotshere" << endl;
operator=(thea);
}
};
int main(){
B b;
b = A();
}
它确实解决了问题,但当我做B;b=b()
,调用A::operator=而不是'b::operator='的输出。为什么呢
我不明白为什么会调用A()。有人知道吗
B
继承A
,因此在构造B
之前,必须构造B
的A
组件。由于您没有指定要调用A
的哪个构造函数,所以编译器选择默认构造函数
编辑(回答问题编辑)
就反复调用一部分而言,这里是你的逻辑错误的地方:你说
它试图调用不存在的B::operator=
,因此它再次调用B(const A&)
但事实并非如此:它不是调用A的操作符=
,而是调用编译器免费为您生成的B的操作符=
。要验证,请将行更改为A::operator=(thea)代码>,无限递归将消失
那么为什么是无限递归呢?回想一下,生成的赋值运算符的签名是
B& operator=(const B& b)
编译器需要一个B
的实例才能传递给操作符=
,但您正在传递一个A
的实例。但是,您定义了一个B
的构造函数,它接受常量a&
。这足以让编译器通过创建一个临时B,从常量a&
构造它,并调用B::operator=
来生成正确的调用,如下所示:
B temp(thea); <<== At this point, you're in an infinite recursion
B::operator=(temp);
我不明白为什么会调用A()。有人知道吗
B
继承A
,因此在构造B
之前,必须构造B
的A
组件。由于您没有指定要调用A
的哪个构造函数,所以编译器选择默认构造函数
编辑(回答问题编辑)
就反复调用一部分而言,这里是你的逻辑错误的地方:你说
它试图调用不存在的B::operator=
,因此它再次调用B(const A&)
但事实并非如此:它不是调用A的操作符=
,而是调用编译器免费为您生成的B的操作符=
。要验证,请将行更改为A::operator=(thea)代码>,无限递归将消失
那么为什么是无限递归呢?回想一下,生成的赋值运算符的签名是
B& operator=(const B& b)
编译器需要一个B
的实例才能传递给操作符=
,但您正在传递一个A
的实例。但是,您定义了一个B
的构造函数,它接受常量a&
。这足以让编译器通过创建一个临时B,从常量a&
构造它,并调用B::operator=
来生成正确的调用,如下所示:
B temp(thea); <<== At this point, you're in an infinite recursion
B::operator=(temp);
B::operator=接受一个B&,但您要传递一个a&,因此它必须从a构造一个新的B,这会导致无限递归
至于你的第二个问题。您定义了B::operator=(常数A&),但仍然会自动生成一个接受常数B&的赋值运算符,并且自动生成的赋值运算符会调用基本赋值运算符。B::operator=接受一个B&,但您正在传递一个A&,因此它必须从A构造一个新的B,这导致了无限递归
至于你的第二个问题。您定义了B::operator=(const A&),但接受const B&的赋值运算符仍然自动生成,并且自动生成的赋值运算符调用基本赋值运算符。我明白了,但我应该澄清的是,我想知道为什么会重复调用A(),但我应该澄清的是,我想知道为什么会重复调用A()?