RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1440614
Accepted
Stanley
Stanley
Asked:2022-08-19 03:45:19 +0000 UTC2022-08-19 03:45:19 +0000 UTC 2022-08-19 03:45:19 +0000 UTC

C ++中的复制和交换习语

  • 772

这不是我第一次提出关于折线问题的问题。这次我想在我的代码中讨论“C++ 中的复制和交换成语”。如果您有兴趣,可以在此处阅读问题说明。

因此,在我的代码中,我实现了 Copy-and-Swap 习惯用法:

void swap(Loman& a) {
        std::swap(size, a.size);
        std::swap(data, a.data);
    }
 
    Loman& operator=(const Loman& a)
    {
            Loman tmp(a);
            swap(tmp);
        return *this;
    }

但在我看来,这段代码中有一个逻辑错字,实际上应该这样写:

void swap(Loman& first, Loman& second) {
        std::swap(first.size, second.size);
        std::swap(first.data, second.data);
    }
 
    Loman& operator=(const Loman& a)
    {
            Loman tmp(a);
            swap(*this, tmp);
        return *this;
    }

在我看来, + 运算符中还有一个不必要的操作this-> size = size。如果我删除它,什么都不会改变。

这是整个代码:

#include <iostream>
using namespace std;
class Loman
{
private:
    int i=0;
    int size;
    int* data;
public:
    Loman(int asize) {
        size = 2*asize;
        data = new int[size];
    }
    ~Loman(){
        delete[] data;
        cout<<"Object destroyed\n";
    }
    Loman(const Loman &ob)
    {
        size = ob.size;
        data = new int [size];
        for(int i=0; i<ob.size; i++)
            data[i] = ob.data[i];
    }
    void print(){
        for(i=0; i<size; i++){
            cout<<*(data+i)<<" ";
        }
        cout<<endl;
    }
 
    void scan(){
        cout<<"Input "<<size/2<<" coordinates\n";
        for(int i=0; i<size; i++){
            cin>>*(data+i);
        }
    }
    Loman operator+(Loman& ob){
        this->size = size;
        Loman tmp((size + ob.size)/2);
        for(i=0; i<size; i++)
        {
            tmp.data[i]=*(data + i);//this->data[i]=data[i];
        }
        for(i=size; i<size + ob.size; i++) tmp.data[i] = ob.data[i-size];
        return tmp;
    }
    void swap(Loman& a) {
        std::swap(size, a.size);
        std::swap(data, a.data);
    }
 
    Loman& operator=(const Loman& a)
    {
            Loman tmp(a);
            swap(tmp);
        return *this;
    }
};
int main(){
    Loman first(3);
    Loman second(2);
    first.scan();
    second.scan();
    Loman third(5);
    third=first+second;
    third.print();
    return 0;
}

问题:我关于“+”运算符和交换函数的假设是否正确,如果不是,为什么不呢?
我错过了任何其他错误吗?
是否需要在swap函数中写using std::swap;

c++ классы
  • 1 1 个回答
  • 60 Views

1 个回答

  • Voted
  1. Best Answer
    HolyBlackCat
    2022-08-19T04:15:13Z2022-08-19T04:15:13Z

    我从头开始。

    是否需要在swap函数中写using std::swap;

    这里不需要。using std::swap;,然后swap(x, y);(已经没有)是对任意类型std::的规范调用。swap

    默认情况下,它会调用std::swap,但如果有此类型的函数swap(ADL在其中找到它- 例如,在同一个命名空间中),那么它将被调用。

    但是由于这里你只在内置类型上调用它(而不是在类上),所以仍然没有 ADL,而且没有必要打扰。


    从这里遵循关于您的功能的答案swap。如果您希望以这种方式调用它,那么它一定不能是非静态成员。(因为我们这样做swap(x, y);,而不是x.swap(y);。)

    你写的: - 这是完全错误的,因为这样的函数需要三个对象,而不是两个(结果void swap(Loman &first, Loman &second)是第三个是)。thisx.swap(y, z)

    正确:friend void swap(Loman& first, Loman& second) {...}。有人会认为这样static做可以,但不,ADL 不尊重他。


    添加一个移动构造函数也是值得的(noexcept不要忘记)。之后,最operator=好像这样重写它:

    Loman& operator=(Loman a) noexcept
    {
        swap(*this, a);
        return *this;
    }
    

    那么它将适合同时复制和移动。在任何情况下我都会使用这种形式(即使没有复制或移动构造函数)以免思考。


    Loman operator+(Loman& ob)必须替换为Loman operator+(const Loman &) const以+接受 const 和/或临时对象。

    同样,void print() const.


    Boperator+什么都不做this->size = size;。是同一个变量。


    混淆了到处写字的习惯*(data+i)。你不喜欢data[i]什么?

    另一个令人困惑的想法是将 X 和 Y 混合存储在一个数组中。最好自己制作struct Point {int x, y;}并将其存储在数组中。然后,您无需费心将大小乘以 2。

    • 4

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5