如果之前已经提出并解决了这个话题,请提前抱歉。
我想创建一个带有纯虚函数(抽象类)的基类,这样当从中创建派生类时,用户必须在派生类中实现此函数的主体。关键是在纯虚函数中,我想将派生类型作为参数对象。这可能吗?
例如:
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对象来实现函数体?
提前致谢!
答案 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中重写该函数两次。依此类推其他派生类。
你认为它可以用其他更聪明的方式完成吗?
谢谢!