运算符重载复制构造和 = 运算符

Operator Overloading copy constructs and = operator

提问人:Light 提问时间:7/29/2022 最后编辑:Remy LebeauLight 更新时间:7/29/2022 访问量:151

问:

如何创建将对象复制到新实例化对象的复制构造函数?

另外,如何使用运算符来比较两个对象?==speedTricycle

示例代码如下:

#include <iostream>

class Tricycle
{
private:
    int* speed;
  //static int speedlim;

public:
    Tricycle();
    // copy constructor and destructor use default
    int getSpeed() const { return *speed; }
  //static int getspeedlim() {return speedlim;}
    void setSpeed(int newSpeed) { *speed = newSpeed; }
    Tricycle operator=(const Tricycle&);
  void operator++();
  void operator++(int);
};

  //Tricycle operator++();
  //Tricycle operator++(Tricycle,int);

Tricycle::Tricycle()
{
    speed = new int;
    *speed = 5;
  //speedlim=40;
  }

Tricycle Tricycle::operator=(const Tricycle& rhs){ 
  
    if (this == &rhs)
        return *this;
    delete speed;
    //speed = new int;
    //*speed = rhs.getSpeed();
    return *this;
}

void Tricycle::operator++(){
  (*speed)++;}
void Tricycle::operator++(int){
  (*speed)++;}  

int main()
{
    Tricycle wichita;
  //std::cout << "the speed limit is : " << Tricycle::getspeedlim();; 
    std::cout << "Wichita's speed : " << wichita.getSpeed() << "\n";
    std::cout << "Setting Wichita's speed to 6 ...\n";
    wichita.setSpeed(6);
    Tricycle dallas;
    std::cout << "Dallas' speed : " << dallas.getSpeed() << "\n";
    std::cout << "Copying Wichita to Dallas ...\n";
    wichita = dallas;
    std::cout << "Dallas' speed : " << dallas.getSpeed() << "\n";

  wichita.setSpeed(5);
  wichita++;
  std::cout << "Wichita's speed : " << wichita.getSpeed() << "\n";

  wichita.setSpeed(5);
  ++wichita;
  std::cout << "Wichita's speed : " << wichita.getSpeed() << "\n";
  
    return 0;
}

这是我尝试使用预增量和后增量来增加 .这是答案:speed

Wichita's speed : 5
Setting Wichita's speed to 6 ...
Dallas' speed : 5
Copying Wichita to Dallas ...
Dallas' speed : 5
Wichita's speed : 6
Wichita's speed : 6
C++ 运算符 相等

评论

0赞 jkb 7/29/2022
不相关,但赋值运算符应返回引用:。Tricycle &
1赞 fabian 7/29/2022
使用动态分配的内存有什么意义?如果改用,则无需定义复制和移动构造函数/赋值运算符,因为默认构造函数/赋值运算符就足够了。赋值运算符的返回类型应该是对包含类的引用,不过......speedint
2赞 Some programmer dude 7/29/2022
我建议您阅读此规范实现参考,了解重载运算符。所有超载的运算符都错了。
0赞 Some programmer dude 7/29/2022
至于复制部分,您似乎已经知道如何使用复制分配运算符(嗯,几乎)做到这一点。现在想一想如何在你的复制构造函数中做到这一点。
2赞 Sam Varshavchik 7/29/2022
下面是如何“创建一个复制构造函数,将一个对象复制到新实例化的对象”,这就是你问的:声明构造函数,它是一个构造函数,它接受对此对象的另一个实例的常量引用。然后,在该构造函数中,继续并初始化新对象的所有成员,使其与其他对象相同。复制构造函数没有什么神奇之处,它是一个构造函数,它与任何其他构造函数没有什么不同,只是它的唯一参数是对同一类的另一个实例的常量引用。 就这样。

答:

1赞 Remy Lebeau 7/29/2022 #1

如何创建将对象复制到新实例化对象的复制构造函数?

喜欢这个:

class Tricycle
{
...
public:
    ...
    Tricycle(const Tricycle&);
    ...
};
    
Tricycle::Tricycle(const Tricycle &src)
{
    speed = new int;
    *speed = src.getSpeed(); // or: *(src.speed)

    // or:
    // speed = new int(src.getSpeed()); // or: *(src.speed)
}

另外,如何使用运算符来比较两个对象?==speedTricycle

喜欢这个:

class Tricycle
{
...
public:
    ...
    bool operator==(const Tricycle&) const;
    ...
};
    
bool Tricycle::operator==(const Tricycle &rhs) const
{
    return getSpeed() == rhs.getSpeed();
    // or:
    // return *speed == *(rhs.speed);
}

也就是说,您的代码还存在一些其他问题:

  • Tricycle缺少析构函数来释放分配的,从而泄漏它。编译器生成的默认析构函数是不够的,就像复制构造函数和赋值运算符一样。speed

  • 赋值和预增量需要返回对 的引用,而后增量需要返回 before was updated 的副本。请参阅运算符重载的基本规则和习惯用语是什么?operator=operator++Tricycle&*thisoperator++Tricycle*thisspeed

  • 分配以无效状态离开。它正在释放,但不会重新分配它或将其设置为 NULL。它根本没有理由释放,只需设置它的值即可。operator=speedspeedspeed

试试这个:

class Tricycle
{
private:
    int* speed;
    //static int speedlim;

public:
    Tricycle();
    Tricycle(const Tricycle&);
    ~Tricycle();

    int getSpeed() const { return *speed; }
    //static int getspeedlim() { return speedlim; }
    void setSpeed(int newSpeed) { *speed = newSpeed; }

    Tricycle& operator=(const Tricycle&);
    Tricycle& operator++();
    Tricycle operator++(int);
};


//int Tricycle::speedlim = 40;

Tricycle::Tricycle()
{
    speed = new int(5);
}

Tricycle::Tricycle(const Tricycle &src)
{
    speed = new int(*(src.speed));
}

Tricycle::~Tricycle()
{
    delete speed;
}

Tricycle& Tricycle::operator=(const Tricycle& rhs)
{
    if (this != &rhs)
        *speed = rhs.getSpeed();
    return *this;
}

Tricycle& Tricycle::operator++()
{
    ++(*speed);
    return *this;
}

Tricycle Tricycle::operator++(int)
{
    Tricycle temp(*this);
    ++(*speed);
    return temp;
}  

也就是说,根本没有充分的理由进行动态分配。如果删除了该分配,则默认的编译器生成的析构函数、复制构造函数和复制赋值运算符就足够了,因此您根本不需要定义它们:speed

class Tricycle
{
private:
    int speed;
    //static int speedlim;

public:
    Tricycle();

    int getSpeed() const { return speed; }
    //static int getspeedlim() { return speedlim; }
    void setSpeed(int newSpeed) { speed = newSpeed; }

    Tricycle& operator++();
    Tricycle operator++(int);
};


//int Tricycle::speedlim = 40;

Tricycle::Tricycle()
{
    speed = 5;
}

Tricycle& Tricycle::operator++()
{
    ++speed;
    return *this;
}

Tricycle Tricycle::operator++(int)
{
    Tricycle temp(*this);
    ++speed;
    return temp;
}