C++ 以派生类对象作为参数在基类中声明纯虚函数

C++ 以派生类对象作为参数在基类中声明纯虚函数,c++,arguments,derived-class,base-class,pure-virtual,C++,Arguments,Derived Class,Base Class,Pure Virtual,如果之前已经提出并解决了此主题,请提前致歉 我想创建一个带有纯虚函数(抽象类)的基类,这样当从它创建派生类时,用户有义务在派生类中实现该函数的主体。关键是在纯虚函数中,我希望将派生类型的对象作为参数。可能吗 例如: class Base{ public: virtual void DoSomething (A object1, B object2) = 0; }; class A: public Base{ public: DoSomething(A x, B y) {

如果之前已经提出并解决了此主题,请提前致歉

我想创建一个带有纯虚函数(抽象类)的基类,这样当从它创建派生类时,用户有义务在派生类中实现该函数的主体。关键是在纯虚函数中,我希望将派生类型的对象作为参数。可能吗

例如:

class Base{

 public:
  virtual void DoSomething (A object1, B object2) = 0;
};

class A: public Base{

 public:
  DoSomething(A x, B y) {

   ...
   ...
};

};

class B: public Base{

 public:
  DoSomething(A x, B y) {

   ...
   ...
};

};
我试过了,但编译器抱怨说它对派生类一无所知,我理解,因为它们是在基类之后创建的。有没有办法规避?或者有没有其他方法可以实现我想要的,也就是强制用户使用派生类类型的arguments对象在派生类中实现函数体


提前谢谢

是的,但您需要模板

class AbstractBase
{
}

template <typename D>
class Base : public AbstractBase
{
public:
    virtual D* func() = 0;
};

class Derived : public Base<Derived>
{
public:
    Derived* func() { return this; }
};
类抽象库
{
}
模板
类库:公共抽象库
{
公众:
虚拟D*func()=0;
};
派生类:公共基
{
公众:
派生的*func(){返回此;}
};

最后,为每个派生类型创建一个Base的模板实例化。这意味着,如果您有
类派生1:public Base
类派生2:public Base
,则它们不共享相同的
类;但是由于
Base
继承自非模板化的
AbstractBase
,因此它们都继承自它。
(当然,您可以以正常方式继承派生自。)

编辑:使用常量引用的最终版本:-)

编辑:使用自动ptr的更好版本

///Test-code. place anywhere in global C++ scope for testing
#include <memory>
using std::auto_ptr;
class A;
class B;




class Base{

 public:
  virtual void DoSomething (auto_ptr<A> object1, auto_ptr<B> object2) = 0;
};

class A: public Base{

 public:
  void DoSomething(auto_ptr<A> x, auto_ptr<B> y) { 
    int i=0;
    i++; //test break point
  };

};

class B: public Base{

 public:
  void DoSomething(auto_ptr<A> x, auto_ptr<B> y) { 
    int i=0;
    i++; //test break point
  };

};

bool test()
{
    Base *a = new A;
    Base *b = new B;

    a->DoSomething( auto_ptr<A>(new A), auto_ptr<B>(new B) );
    b->DoSomething( auto_ptr<A>(new A), auto_ptr<B>(new B) );
    return true;
}

static bool invokeTest = test();
///END of test-code
我想知道你为什么需要它


编辑p.p.S.:我仍然想知道为什么需要它:-)?

使用引用和转发声明:

// Forward declaration
class A;
class B;

class Base
{
public:
    virtual void DoSomething(const &A a, const B& b) = 0;
};

class A: public Base
{
public:
    virtual void DoSomething(const &A a, const B& b) /* override */;
};

非常感谢您的及时回复!const ref的解决方案运行良好! 有人问为什么一个人需要这样的东西。我会尽快解释的。我是物理学家,我试图实现物体之间的相互作用

基类应该包含一些对象的公共内容。派生类(A,B,…)应表示具有不同属性的对象。然后,我尝试实现每个对象类型(派生类)的物理以及它与其他对象(其他派生类)的交互。A可以与B或C反应,B可以与A、C或D反应,等等

由于每个对象都有自己的物理特性,并且每个交互都可能不同,因此不能在基类中实现DoSomething函数体。因此,我在基类中使用纯虚函数

例如,A可以与类B或类C的对象交互。那么,我应该在基类中 虚拟无效剂量测定(常数A和对象1,常数B和对象1)=0; 虚拟无效剂量测定(常数A和常数1,常数C和常数1)=0

然后我在派生类A中重写函数两次,对其他派生类也是如此

你认为可以用其他更聪明的方法来做吗


谢谢

听起来您需要模板…您可能需要阅读有关模板的信息。它本身可能不会帮助你解决这个问题,但它可能会给你一些想法。或者是上面的,或者是把参数作为引用/指针,这样你就可以为声明转发声明类了。老实说,我发誓我在阅读了上面关于你的文章后写了下面的回复。尽管这个例子几乎是一字不差的,但我很想知道,对于2个Child类,如果没有指针,
class-Derived1:public-Base
class-Derived2:public-Base
,您将如何编写它。这意味着,正如我所说,
Derived1
Derived2
不在同一类层次结构中——它们有不同的超类(
Base
Base
)。使用模板化的
Base
继承的
AbstractBase
可能是明智的。不,您已经用一个子类做了两次:)但是OP希望在Base中使用
void DoSomething(Derived1,Derived2)
。CRTP不适合这样做,至少不需要大量按摩……哦,是的,不,那不行。但为了清楚起见,我还是更新了我的答案。我会使用(const)reference(因为他通过值传递对象,所以他不拥有对象的所有权)。并且在C++11中不推荐使用
auto_ptr
。@Jarod42:true!我已将示例更改为使用const refs。我也工作。感谢您提到auto_ptr已被弃用。真遗憾,我仍然没有使用C++11:-(
class A;
class B;

class Base{

 public:
  virtual void DoSomething (A * object1, B * object2) = 0;
};

class A: public Base{

 public:
  void DoSomething(A *x, B *y) {

};

};

class B: public Base{

 public:
  void DoSomething(A *x, B *y) {

};

};
// Forward declaration
class A;
class B;

class Base
{
public:
    virtual void DoSomething(const &A a, const B& b) = 0;
};

class A: public Base
{
public:
    virtual void DoSomething(const &A a, const B& b) /* override */;
};