从基础对象(智能)指针复制派生对象

时间:2017-07-18 18:44:49

标签: c++ polymorphism

假设我有两个类BaseDerived,它们有一个变量来判断对象是否为Derived类型:

class Base {
public:
    Base() : is_derived(false) {}
    bool is_derived;
};

class Derived : public Base {
public:
    Derived() : is_derived(true) {}
    int derived_only_member;
};

我有std::set std::shared_ptrBase个对象:

std::set<std::shared_ptr<Base> > bases;
// Populate this set one way or another

我需要遍历集合并仅将Derived个对象复制到另一组类似的Base共享指针中:

std::set<std::shared_ptr<Base> > copies;
for(auto &b: bases) {
    if(b->is_derived) {
        copies.insert(/*Somehow copy the `Derived` object and assign a `std::shared_ptr<Base>` to it */);
    }
}

如果我知道Base指针指向Derived对象,我该如何复制它以使副本具有derived_only_member的相同值?

有没有办法在没有复制构造函数的情况下执行此操作,该复制构造函数具有Derived具有BaseDerived不具有的每个成员变量的参数?我String foo(String m, Function<Double, Options> r) {}的真实版本有很多成员,所以这是不切实际的。

1 个答案:

答案 0 :(得分:0)

  

有没有办法在没有复制构造函数的情况下执行此操作,该复制构造函数具有Derived所拥有的每个成员变量的参数且Base不会?

复制构造函数不需要每个成员变量的参数。编译器也已为您生成一个。

你需要的是演员:

std::set<std::shared_ptr<Base> > copies;
for(auto &b: bases) {
    if(b->is_derived) {
        copies.insert(std::make_shared<Derived>(static_cast<Derived>(*b)));
                                             // ^^^^^^^^^^^^^^^^^^^^^  ^ 
    }
}

注意:

您甚至不需要is_derived成员来检查来自Base的实例。您可以改为使用dynamic_cast

std::set<std::shared_ptr<Base> > copies;
for(auto &b: bases) {
    Derived* org = dynamic_cast<Derived*>(b.get());
    if(org) {
        copies.insert(std::make_shared<Derived>(*org));
    }
}