C++ 在C+中,是否有一种方法可以通过值将纯抽象类的所有子类传递给函数+;?

C++ 在C+中,是否有一种方法可以通过值将纯抽象类的所有子类传递给函数+;?,c++,C++,假设我有两个类A和B,其中A是一个纯抽象类,具有纯虚函数,B继承自A并实现纯虚函数。如果我有一个函数g(),我想通过值将a的子类的任何实例传递给它(这样我就可以在不改变原始实例的情况下对其进行变异),你会怎么做? 我知道以下代码不符合我的目的: void g(A myObject) {} //doesn't work since A contains a pure virtual function void g(A* myObject) {} //code compiles, but chan

假设我有两个类
A
B
,其中
A
是一个纯抽象类,具有纯虚函数,
B
继承自
A
并实现纯虚函数。如果我有一个函数
g()
,我想通过值将
a
的子类的任何实例传递给它(这样我就可以在不改变原始实例的情况下对其进行变异),你会怎么做? 我知道以下代码不符合我的目的:

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 

我会复制这个实例并创建一个指向它的指针,然后传递到一个像上面这样的函数中吗?还是有更干净的方法来实现这一点?

我认为这里的最佳实践是利用
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;
}
#包括
#包括
阶级基础
{
公众:
虚空集_str(std::string)=0;
虚空打印()=0;
虚拟std::unique_ptr clone()=0;
};
派生类:公共基
{
私人:
std::string _str;
公众:
std::unique_ptr clone()覆盖{
return std::make_unique(*this);
}
无效集\u str(std::string str)重写{
这个->_str=str;
}
void print()覆盖{
标准:cout_str set_str(“内部”);
obj->print();
}
int main(){
派生obj;
对象集_str(“外部”);
foo(obj.clone());
obj.print();
返回0;
}

如果A中确实是纯虚函数,那么什么会阻止复制呢?如果A可以从其子类创建副本,那么您就可以对原始对象进行切片,并且只保留A中存在的字段

如果要防止修改,可以:

  • 用引发异常的函数替换纯虚函数。如果您试图在非子类对象上使用该函数,则类a将成为可创建的,而它仍将中断
  • 使用上述定义的函数在层次结构中插入A1类,并在
    g
这两种方法都会创建原始对象的副本并传递(切片的)副本

您还可以使用常量引用:

void g(const A& myObject);

这将传递对原始对象的引用,但如果您试图修改它,编译器将引发错误。

因此,要使用此方法,我将克隆传递到函数内部函数中的对象,然后在不更改原始对象的情况下对其进行变异?
f(Base*obj){Base*c=obj->clone()}
谢谢,这正是我需要的!