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

时间:2013-12-22 21:08:23

标签: 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 B: public Base{

 public:
  DoSomething(A x, B y) {

   ...
   ...
};

};

我试过但编译器抱怨说它对派生类一无所知,我理解它们是因为它们是在Base类之后创建的。有办法规避吗?或者是否有另一种方法可以做我想要的,也就是说,要求用户在派生类中使用派生类类型的参数arguments对象来实现函数体?

提前致谢!

4 个答案:

答案 0 :(得分:1)

使用引用和转发声明:

// 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 */;
};

答案 1 :(得分:0)

是的,但您需要模板。

class AbstractBase
{
}

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

class Derived : public Base<Derived>
{
public:
    Derived* func() { return this; }
};

您最终会为每个派生类型提供Base的模板实例化。这意味着如果您有class Derived1 : public Base<Derived1>class Derived2 : public Base<Derived2>,那么他们共享相同的Base类;但由于Base<T>继承自非模板AbstractBase,因此它们都继承了这一点。 (当然,你可以用正常的方式继承Derived。)

答案 2 :(得分:0)

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

///Test-code. place anywhere in global C++ scope for testing
class A;
class B;

class Base{

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

class A: public Base{

 public:
  void DoSomething(const A & object1, const B & object2) { 
    int i=0;
    i++; //test break point
  };

};

class B: public Base{

 public:
  void DoSomething(const A & object1, const B & object2) { 
    int i=0;
    i++; //test break point
  };

};

bool test()
{
    A a;
    B b;

    a.DoSomething( A(), B() );
    b.DoSomething( A(), B() );
    return true;
}

static bool invokeTest = test();
///END of test-code

编辑:使用auto_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

原始回答

如果参数是指针,那么它应该起作用:

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) {

};

};
P.S:我想知道你为什么需要它?

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

答案 3 :(得分:0)

非常感谢您的快速回答! const ref的解决方案效果很好! 有人在问为什么人们会需要这样的东西。我会尽快解释一下。我是物理学家,我正在尝试实现对象之间的一些交互。

Base类应包含对象的一些常见内容。派生类(A,B,...)应表示具有不同属性的对象。然后,我尝试实现每个对象类型(派生类)的物理特性及其与其他对象(另一个派生类)的交互。 A可与B或C反应,B与A,C或D等反应......

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

例如,A可以与B类或C类的对象进行交互。然后,我应该在Base类中进行交互 virtual void DoSomething(const A&amp; object1,const B&amp; object1)= 0; virtual void DoSomething(const A&amp; object1,const C&amp; object1)= 0;

然后我在派生类A中重写该函数两次。依此类推其他派生类。

你认为它可以用其他更聪明的方式完成吗?

谢谢!