简体   繁体   English

有没有办法将纯抽象 class 的所有子类按值传递给 C++ 中的 function?

[英]Is there a way to pass by value all the sub-classes of an pure abstract class to a function in C++?

Say I had 2 classes A and B , where A is a pure abstract class with a pure virtual function and B inherits from A and implements the pure virtual function.假设我有 2 个类AB ,其中A是纯抽象 class 和纯虚拟 function 和BA继承并实现纯虚拟 ZC1C425268E68385D1AB5074C17A94F1。 If I then have a function g() that I want to pass any instance of a subclass of A by value to (so I could mutate it without changing the original instance), how would you do that?如果我有一个 function g()我想将A的子类的任何实例按值传递给(所以我可以在不更改原始实例的情况下对其进行变异),你会怎么做? I know that the following code does not fit my purposes:我知道以下代码不符合我的目的:

void g(A myObject) {} //doesn't work since A contains a pure virtual function

void g(A* myObject) {} //code compiles, but changes the original instance 

Would I just copy the instance and make a pointer to it and pass into a function like above?我是否只需复制实例并创建一个指向它的指针并像上面一样传递到 function 中? Or is there a cleaner way to do this?还是有更清洁的方法来做到这一点?

I think the best practice here is to leverage clone() method:我认为这里的最佳做法是利用clone()方法:

#include <iostream>
#include <memory>

class Base
{
public:
    virtual void set_str(std::string) = 0;
    virtual void print() = 0;
    virtual std::unique_ptr<Base> clone() = 0;
};

class Derived: public Base
{
private:
    std::string _str;
public:
    std::unique_ptr<Base> clone() override { 
        return std::make_unique<Derived>(*this); 
    }
    void set_str(std::string str) override {
        this->_str = str;
    }
    void print() override {
        std::cout << this->_str << std::endl;
    }
};

void foo(std::unique_ptr<Base> obj) {
    obj->set_str("inside");
    obj->print();
}

int main() {
    Derived obj;
    obj.set_str("outside");
    foo(obj.clone());
    obj.print();
    return 0;
}

What prevent the copy if indeed the pure virtual function in A. If A could be copy created from its child classes, you would have sliced the original object and only kept the fields present in A.如果 A 中确实是纯虚拟 function,那么是什么阻止了复制。如果 A 可以从其子类创建复制,您将切割原始 object 并仅保留 A 中存在的字段。

If you want to prevent modifications, you could:如果您想防止修改,您可以:

  • replace the pure virtual function with a function raising an exception.将纯虚拟 function 替换为 function 引发异常。 Class A would become creatable while it would still break if you tried to use the function on a non subclassed object.如果您尝试在非子类 object 上使用 function,Class A 将变得可创建,但仍会中断。
  • insert a A1 class in the hierachy with the above defined function and use it in g使用上面定义的 function 在层次结构中插入 A1 class 并在g中使用它

This both methods create a copy of the original object and pass that (sliced) copy这两种方法都会创建原始 object 的副本并传递该(切片)副本

You could also use a const reference:您还可以使用 const 引用:

void g(const A& myObject);

This will pass a reference to the original object, but the compiler will raise an error if you try to modify it.这将传递对原始 object 的引用,但如果您尝试修改它,编译器将引发错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM