当前位置: 首页 > 知识库问答 >
问题:

是否可以将C复制构造函数用于其他目的?

施晗昱
2023-03-14

我指的是克隆。这里有一个简化的html" target="_blank">示例:我有对象,一些是正方形,一些是长方体,它们都是Object2D。每个都有一个唯一的id。

在这个系统中,我不需要对象副本的典型含义。当对象按值传递、按值返回和。。。在这个系统中,每个对象都是唯一的,因此我们不需要典型的复制构造函数。两个方块的id至少不同。因此,我正在使用复制构造函数进行克隆。在克隆过程中,我将深度复制除id之外的树结构。

#include <iostream>
#include <string>
#include <memory>
#include <cstdlib>
#include <vector>
int offset(){
    return rand()%100-50;
}
int location(){
    return rand()%10000-5000;
}
class Object2D{
public:
    int x_, y_;
    int id;
    static int count;
    Object2D(int x, int y):x_(x), y_(y){
        id=count++;
    }
};
int Object2D::count=0;
class Square: public Object2D{
public:
    int getParent(){return containedBy_->id;}
    Square(Object2D* containedBy, int size):
            Object2D(containedBy->x_+offset(), containedBy->y_+offset()),
            containedBy_(containedBy),size_(size){
        std::cout<<"Square constructor"<<std::endl;
    }
    Square(const Square& other):
            Object2D(other.x_-other.containedBy_->x_, other.y_-other.containedBy_->y_), 
            containedBy_(other.containedBy_), size_(other.size_){
        std::cout<<"Square clone"<<std::endl;
    }
private:    
    Object2D* containedBy_;
    size_t size_;
};
class Box:public Object2D{
private:
    size_t l_;size_t h_;
    std::vector<std::shared_ptr<Square>> all;
public:
    void addSquare(int size){
        auto temp = std::make_shared<Square>(this, size);
        all.push_back(std::move(temp));
    }
    const std::vector<std::shared_ptr<Square>>& getAll() const{
        return all;
    }
    Box(int x, int y, size_t l, size_t h):
            Object2D(x,y), l_(l), h_(h){}
    Box(const Box& other):Object2D(location(), location()){// clone the other box, put cloned squares in
        for(const auto& item:other.getAll()){
            all.push_back(std::make_shared<Square>(*item));
        }
    }
    void showOffsets(){
        std::cout<<"show offsets of all components for container"<<id<<":";
        for(const auto& item: all){
            std::cout<<item->id<<"("<<item->x_-x_<<","<<item->y_-y_<<")"<<" ";
        }
        std::cout<<std::endl;
    }
};

int main()
{
    Box b(100,100,100,100);
    std::cout<<"before do it"<<std::endl;

    b.addSquare(10);
    Box c(b);
    std::cout<<b.id<<c.id<<std::endl;

    b.showOffsets();
    c.showOffsets();
    return 0;
}

这里我克隆了一个长方体,我还需要克隆包含的正方形,并保持它们的偏移。克隆的对象将具有新的ID,这些ID都是唯一的。

使用复制构造函数进行克隆是一个好主意吗?请注意,在这种情况下,复制构造函数的行为将不同于典型的复制构造函数,因此我需要禁止以任何方式调用通常期望的复制构造函数,例如我不能使用向量来包含平方,因为简单的向量擦除将调用不会保留id的复制构造函数。因此我使用了智能指针。

第二,为什么在克隆过程中不复制偏移量?这是我想保留的东西。

结果:

before do it
Square constructor
Square clone
02
show offsets of all components for container0:1(36,33) 
show offsets of all components for container2:3(-1879,2256) 

共有1个答案

唐焕
2023-03-14

是的,您可以定义自己的复制构造函数。

然而,正如您已经指出的那样,这样您会发现很难“禁止”您不明确想要的拷贝。

我的建议是:给你的对象一个克隆函数,然后删除复制构造函数(也可能是复制操作符)。

这样,只有在明确打算克隆时才能进行克隆。

 类似资料:
  • 主要内容:默认拷贝构造函数拷贝和复制是一个意思,对应的英文单词都是 。 对于计算机来说,拷贝是指用一份原有的、已经存在的数据创建出一份新的数据,最终的结果是多了一份相同的数据。例如,将 Word 文档拷贝到U盘去复印店打印,将 D 盘的图片拷贝到桌面以方便浏览,将重要的文件上传到百度网盘以防止丢失等,都是「创建一份新数据」的意思。 在 C++ 中,拷贝并没有脱离它本来的含义,只是将这个含义进行了“特化”,是指用已经存在的对

  • 我用模板复制构造函数写了一段代码,以便更好地理解这个概念,因为我是新手,但是下面的代码无法编译 在Visual Studio中编译上述代码时出现以下错误:- 错误:- 严重性代码描述项目文件行抑制状态错误C2558类“网格”:没有可用的复制构造函数或复制构造函数被声明为“显式” 我试图用E替换参数的模板,但它显示了更多的错误(奇怪的错误) 错误: 严重性代码描述项目文件行抑制状态错误LNK2019

  • 我查看了我的pycharm项目,注意到有2个不在那里,查看了我所有的IDE版本,没有。现在我100%确定我做了这些项目,所以我的问题是pycharm对它能容纳的项目有限制吗?我注意到,当我试图用我已经拥有的大量项目创建一个新项目时,pycharm加载新项目窗口的速度似乎很慢,或者有时根本无法加载,我必须多次创建项目才能注册。 希望你们能回答这个问题

  • 问题内容: 我最近在一个类中看到了这个构造函数: 没有其他构造函数。 是否有一个原因?Java自动创建一个默认的构造函数,那么为什么要显式声明一个呢?还是以与将大括号用于单语句if语句相同的方式视为一种好习惯- 如果以后添加其他构造函数而您忘记了没有默认值…? 问题答案: 有几点要点,不太可能是您在这种情况下看到它的原因。 它为您提供了设置断点的方法。 您可以将其设为非公开 至于“以防以后添加其他

  • 问题内容: 我不明白为什么主要方法必须是静态的。我了解静态变量,但静态方法很难掌握。是否存在静态方法,以便人们可以在两个不会相互冲突的类中创建两个具有相同名称的方法? 另外,我不明白为什么我不能创建静态构造函数。 谁能帮助解释这个概念? 问题答案: Java有 [静态构造函数] 静态初始化块,可以将其视为“静态构造函数”: 无论如何,主类中唯一 必须 是静态的方法是方法。这是因为调用它之前 没有

  • 我对复制构造函数是新手,当我开始使用向量时,似乎无法让它们工作。 我在编译时遇到的错误是: 机器人cpp:复制构造函数中的Robot::Robot(const Robot 如何在复制构造函数中复制向量数组?