4

我想编写一个适用于特定层次结构中的任何派生类的函数,而无需修改抽象类输入参数:

class A {
public:
    A(int val): m_i(val) { }
    virtual void add(int i) = 0;

    int m_i;
};

class B: public A {
public:
    B(int val): A(val) { }
    B(): A(0) { }
    virtual void add(int i) { m_i += i; }
};

class C: public A {
public:
    C(int val): A(val) { }
    C(): A(0) { }
    virtual void add(int i) { m_i += i*2; }
};

int f(const A& base_class)
{
    // how to create a concrete copy of class base_class?
    base_class.add(5);
}

这里 f() 应该适用于 B 和 C,但我无法创建具体类的副本,因为我不知道实际类型,除非我使用 dynamic_cast。

是否有另一种方法来解决这个问题或者应该只使用dynamic_cast?

4

3 回答 3

3

通常称为虚拟构造函数习语的典型方法是定义另一个虚拟方法来克隆具体类,使其在抽象基中为虚拟,并在不知道其类型的情况下根据需要调用它以生成所需类的实例:

class A {
public:
    A(int val): m_i(val) { }
    virtual void add(int i) = 0;
    virtual A* clone() const = 0; // Override in derived classes to return new B/C
    int m_i;
};
于 2013-03-28T14:33:49.473 回答
1

从您的问题中不清楚为什么您甚至需要制作副本。

但是,如果你这样做,你可以有一个clone()方法:

class A {
public:
    virtual A* clone() const = 0;
};

class B: public A {
public:
    virtual B* clone() const { return new(*this); }
};

class C: public A {
public:
    virtual C* clone() const { return new(*this); }
};
于 2013-03-28T14:33:58.113 回答
1

问题是您正在传递const A&add不是一种const方法,如果您拿走const修饰符,那么这有效:

int f(A& base_class)
{
    // how to create a concrete copy of class base_class?
   base_class.add(5);

   ///Need a return here
}

我正在使用gcc,真正告诉你发生了什么的错误是:

error: no matching function for call to 'A::add(int&) const'
  base_class.add(a);                                  ^^^^^  

no known conversion for implicit 'this' parameter from 'const A*' to 'A*'
                                                        ^^^^^^^^

根据您的回复,另一个选项是 makem_i mutable并使成员方法const如下所示:

class A {
  public:
    A(int val): m_i(val) { }
    virtual void add(int i) const = 0;

  protected:
    mutable int m_i;
};

class B: public A {
 public:
    B(int val): A(val) { }
    B(): A(0) { }
    virtual void add(int i) const { m_i += i; }
};

class C: public A {
  public:
    C(int val): A(val) { }
    C(): A(0) { }
    virtual void add(int i) const { m_i += i*2; }
};

int f(const  A& base_class)
{
    base_class.add(5) ;

    //Need a return here
}
于 2013-03-28T14:38:07.743 回答