首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >是否可以将C++复制构造函数用于其他目的?

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

Stack Overflow用户
提问于 2018-06-07 03:19:47
回答 1查看 121关注 0票数 2

其他目的,我指的是克隆。这里有一个简化的例子:我有一些对象,一些是正方形,一些是长方体,它们都是Object2D。每一个都有一个唯一的id。

在这个系统中,我不需要对象副本的典型含义。典型的复制构造函数用于通过值传递对象、通过值返回对象以及...在这个系统中,每个对象都是唯一的,所以我们不需要典型的复制构造函数。两个正方形至少在id上是不同的。因此,我使用复制构造函数来创建克隆。在克隆过程中,我将深度复制除id之外的树结构。

代码语言:javascript
复制
#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;
}

在这里我克隆了一个长方体,我还需要克隆包含的方块,并保留它们的偏移量。克隆的对象将具有新的ids,这些ids都是唯一的。

问题

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

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

结果:

代码语言:javascript
复制
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) 
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-07 03:54:50

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

但是,正如您已经注意到的,通过这种方式,您将发现很难“禁止”那些您不想显式使用的副本。

我的建议是:给你的对象一个clone()函数,然后复制构造函数(也可以是delete操作符)。

通过这种方式,您仅在明确打算克隆时才进行克隆。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50728043

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档