C++ 复制构造函数调用无限循环,尽管有引用调用

C++ 复制构造函数调用无限循环,尽管有引用调用,c++,copy-constructor,C++,Copy Constructor,调用循环的代码: Foo temp = Foo(token.substr(0,i)); this->leftExpression = temp; Foo::Foo(const Foo& a_expr){ this->expr = a_expr.expr; this->tokens = a_expr.tokens; this->stringtoken = a_expr.stringtoken; } 具有声明为: class Foo{

调用循环的代码:

Foo temp = Foo(token.substr(0,i));
this->leftExpression = temp;
Foo::Foo(const Foo& a_expr){
    this->expr = a_expr.expr;
    this->tokens = a_expr.tokens;
    this->stringtoken = a_expr.stringtoken;
}
具有声明为:

class Foo{
    private:
        std::string expr;
        std::vector <Bar*> tokens;
        std::vector <std::string> stringtoken;
调用这个循环的是什么

编辑:

分配操作员:

Foo& Foo::operator=(const Foo& a_expr){
    Foo temp(a_expr);
    std::swap(*this, temp);
    return (*this);
}

aa这就是您的问题:赋值运算符创建一个副本并调用
std::swap
,然后调用赋值运算符

您可以在不使用
std::swap
的情况下实现赋值运算符,也可以在不使用默认实现的情况下实现
swap
,而使用。

问题在于:

std::swap(*this, temp);
std::swap
的默认实现使用赋值,因此从赋值操作符调用它时会出现无限递归

如果确实需要编写自己的赋值运算符,请编写自己的
swap
,例如:

void Foo::swap(Foo & other) {
    using std::swap;
    swap(expr, other.expr);
    // and for all other members
}

Foo& Foo::operator=(Foo temp){
    this->swap(temp);
    return (*this);
}

在这种情况下,看起来所有成员都可以正确复制(尽管您可能需要小心
标记中的哑指针)。如果是这样的话,那么就根本不需要编写自己的析构函数、复制构造函数或复制赋值运算符——只要让隐式运算符做正确的事情就行了。

我只能告诉你一件事:这不是由你向我们展示的代码引起的。请粘贴一个。你发布的代码没有明显的错误(虽然副本是不必要的;为什么不直接编写
Foo temp(…);
?)。您可以发布一个完整的测试用例来演示错误吗?向我们展示
Foo(token.substr(0,i));
调用的构造函数,因为
token.substr(0,i)
肯定不是
const Foo&
。另外,如果
this->leftExpression=temp;
是问题的一部分,请向我们展示
Foo::operator=(const Foo&)的实现
。你确定它在调用复制构造函数吗?令牌是一个
Foo
?这是否意味着我实现
操作符=
的方式在任何情况下都不会起作用?@Alexandrubarbosie请看我回答中关于复制和交换习惯用法的链接,其中解释了如何正确执行该操作。@Alexandrubarbarbosie:如果你特别注意,它可能会起作用sed
std::swap
用于您的类。但这将是一种相当复杂的方法。您可以阅读更多有关复制和交换习惯用法的内容。@DanielFrey显然我误解了它,因为这是我在提出此实现之前读到的内容。@Alexandrubarbosie:那里的示例以非成员身份实现了
swap
(friend)函数,然后调用
swap(*this,other)
-而不是
std::swap
。这与我的成员函数示例非常相似-在某些方面更好,因为它重载
std::swap