C++ 为=重载使用复制构造函数

C++ 为=重载使用复制构造函数,c++,operator-overloading,copy-constructor,assignment-operator,copy-and-swap,C++,Operator Overloading,Copy Constructor,Assignment Operator,Copy And Swap,我有一个有两个向量的类:一个int和一个Str。现在我想定义一个复制构造函数,这样元素的顺序就颠倒了;e、 如果a=(1,你好),(2,世界)我写auto b=a我得到b=(2,世界),(1,你好)。这是完美的工作。我遇到的问题是重载=运算符,以便使用复制构造函数。这是我的类加副本构造函数: 等级 { 私人: 静态整型拷贝; std::向量i; std::向量s; 公众: grade(){copies++;}; 等级(整数,标准::字符串); void printval(); 无效加法器(int

我有一个有两个向量的类:一个
int
和一个
Str
。现在我想定义一个复制构造函数,这样元素的顺序就颠倒了;e、 如果
a=(1,你好),(2,世界)
我写
auto b=a我得到
b=(2,世界),(1,你好)
。这是完美的工作。我遇到的问题是重载
=
运算符,以便使用复制构造函数。这是我的类加副本构造函数:

等级
{
私人:
静态整型拷贝;
std::向量i;
std::向量s;
公众:
grade(){copies++;};
等级(整数,标准::字符串);
void printval();
无效加法器(int,std::string);
int getcount();
坡度(坡度和obj)
{
std::vector::reverse_迭代器strIt=obj.s.rbegin();
for(std::vector::reverse_iterator numIt=obj.i.rbegin();
numIt!=obj.i.rend();++numIt)
{
这->加法器(*numIt,*strIt);
strIt++;
}
}
等级运算符=(等级);
};
当我重载
=
运算符时,会调用构造函数,问题是该值没有传递给LHS变量。这里是重载的
=

grade-grade::operator=(grade-cpy)
{
grade newer=cpy;//按预期调用复制构造函数
return cpy;//没有错误,但LHS变量返回空值。
}
我的主要职能是:

intmain()
{
c2级(1,“你好”);
c1级;
c2.加法器(4,“世界”);
c2.printval();

std::cout您想要的是复制和交换习惯用法:

#include <algorithm>
grade &grade::operator=( grade cpy ) {
    using std::swap;
    swap( i, cpy.i );
    swap( s, cpy.s );
    return *this;
}
#包括
等级和等级::运算符=(等级cpy){
使用std::swap;
掉期(i,cpy.i);
掉期(s,cpy.s);
归还*这个;
}

您需要的是复制和交换习惯用法:

#include <algorithm>
grade &grade::operator=( grade cpy ) {
    using std::swap;
    swap( i, cpy.i );
    swap( s, cpy.s );
    return *this;
}
#包括
等级和等级::运算符=(等级cpy){
使用std::swap;
掉期(i,cpy.i);
掉期(s,cpy.s);
归还*这个;
}

实现assignment运算符的最简单方法是:

其中swap是一个函数,它接受两个
等级
s并交换其值:

void swap( grade& lhs , grade& rhs )
{
    using std::swap;

    swap( lhs.first_member  , rhs.first_member  );
    swap( lhs.second_member , rhs.second_member );
    swap( lhs.third_member  , rhs.third_member  );
    ...
}
请注意,
swap()
std::swap()
std::swap()
的重载/专门化,默认情况下使用assigment操作符执行交换,因此如果使用它,将导致无限递归。您需要做的是编写自己的swap重载,它执行成员对成员的交换(如上例所示)


请注意,您应该使用非限定的
swap()
来不禁用ADL,并让编译器查找成员的自定义
swap()
重载(如果它们提供了重载)或标准库版本。

实现assignment操作符的最简单方法是:

其中swap是一个函数,它接受两个
等级
s并交换其值:

void swap( grade& lhs , grade& rhs )
{
    using std::swap;

    swap( lhs.first_member  , rhs.first_member  );
    swap( lhs.second_member , rhs.second_member );
    swap( lhs.third_member  , rhs.third_member  );
    ...
}
请注意,
swap()
std::swap()
std::swap()
的重载/专门化,默认情况下使用assigment操作符执行交换,因此如果使用它,将导致无限递归。您需要做的是编写自己的swap重载,它执行成员对成员的交换(如上例所示)


请注意,您应该使用非限定的
swap()
来不禁用ADL,并让编译器查找成员的自定义
swap()
重载(如果它们提供了重载)或标准库版本。

更改复制构造函数和赋值运算符,如下所示:

grade::grade(const grade& cpy)
{
    *this = cpy;
}

grade& grade::operator=(const grade& cpy)
{
    if (this == &cpy)
        return *this;

    std::vector<std::string>::reverse_iterator strIt = cpy.s.rbegin();
    for (std::vector<int>::reverse_iterator numIt=cpy.i.rbegin();numIt!=cpy.i.rend();++numIt)
    {
        this->adder(*numIt, *strIt);
        strIt++;
    }

    return *this;
}
object::object(const object& input)
{
    *this = input;
}

object& object::operator=(const object& input)
{
    if (this == &input)
        return *this;

    Deallocate();
    Allocate(input);
    Initialize(input);

    return *this;
}

如下更改复制构造函数和赋值运算符:

grade::grade(const grade& cpy)
{
    *this = cpy;
}

grade& grade::operator=(const grade& cpy)
{
    if (this == &cpy)
        return *this;

    std::vector<std::string>::reverse_iterator strIt = cpy.s.rbegin();
    for (std::vector<int>::reverse_iterator numIt=cpy.i.rbegin();numIt!=cpy.i.rend();++numIt)
    {
        this->adder(*numIt, *strIt);
        strIt++;
    }

    return *this;
}
object::object(const object& input)
{
    *this = input;
}

object& object::operator=(const object& input)
{
    if (this == &input)
        return *this;

    Deallocate();
    Allocate(input);
    Initialize(input);

    return *this;
}

你问:
为什么c1保持空白??

答案是赋值运算符不会修改对象本身。以下是您的代码:

grade grade::operator=(grade cpy)
{
  grade newer=cpy; //Calls the copy constructor as expected
  return cpy; //No error but blank value is returned to the LHS variable.
}

该方法返回输入参数
cpy
的副本,但不修改当前实例。执行此方法时,
*this
是“LHS变量”,并且根本不被修改。在此方法中(运算符重载,您需要实际修改当前实例的成员变量!

您问:
为什么c1保持空白??

答案是赋值运算符不会修改对象本身。以下是您的代码:

grade grade::operator=(grade cpy)
{
  grade newer=cpy; //Calls the copy constructor as expected
  return cpy; //No error but blank value is returned to the LHS variable.
}

该方法返回输入参数
cpy
的副本,但不修改当前实例。当此方法执行时,
*this
是“LHS变量”,并且根本没有被修改。在此方法中(运算符重载,您需要实际修改当前实例的成员变量)

不要说在堆栈溢出问题中“完美工作”。在堆栈溢出问题中永远不要说“完美工作”。
swap
将调用
操作符=
,导致无限递归。您需要交换单个成员变量。要么这样做,要么实现
swap()的重载
对于您的类。@AdamH.Peterson您的想法是为您自己的类型重载
swap
。啊,我看到您在答案中添加了重载。(但您可能应该在示例
swap()
中演示memberwise swap)您使用限定的
std::swap
将禁用ADL,这意味着如果
第一个成员
(等)实现它们自己的重载,它们将不会被考虑。您应该将
using std::swap;
放入函数中,然后调用
swap()
unqualified.@AdamH.Peterson我总是忘记ADL问题,谢谢
swap
将调用
operator=
,导致无限递归。您需要交换单个成员变量。要么这样,要么实现
swap()的重载
对于您的类。@AdamH.Peterson的想法是您为自己的类型重载
交换
。啊,我看到您在答案中添加了重载。(但您可能应该在示例
swap()
中演示memberwise交换)您对qualifi的使用