所以我试图将一些实现接口*的类中的一些通用代码移到抽象基类中。但是,抽象基类需要了解一些派生类想要如何做事的信息,以便准确地确定要做什么。但是,我不完全确定是否应该使用纯虚函数或受保护的成员变量来实现它。
我将举一个简单的例子来描述我正在尝试做的事情。
界面:
class SomeInterface
{
public:
void DoSomething() = 0;
// ...
};
我试图使用纯虚函数实现的抽象基类:
class AbstractBase : public SomeInterface
{
public:
virtual void DoSomething()
{
for (int i = 0; i < GetNumIterations(); i++)
{
// Call implementation in derived classes, for example
DoSomethingImpl();
}
}
protected:
virtual void DoSomethingImpl() = 0;
virtual int GetNumIterations() = 0;
};
派生类:
class Derived1 : public AbstractBase
{
protected:
virtual void DoSomethingImpl()
{
// Do actual work.
}
virtual int GetNumIterations()
{
return 5;
}
};
另一个派生类:
class Derived2 : public AbstractBase
{
protected:
virtual void DoSomethingImpl()
{
// Do actual work.
}
virtual int GetNumIterations()
{
return 1;
}
};
或者另一种方法是使用受保护的变量:
class AbstractBase
{
public:
virtual void DoSomething()
{
for (int i = 0; i < numIterations; i++)
{
// Call implementation in derived classes, for example
DoSomethingImpl();
}
}
protected:
virtual void DoSomethingImpl() = 0;
int numIterations;
};
派生的将是:
class Derived1 : public AbstractBase
{
public:
Derived1()
: numIterations(5)
{
}
protected:
virtual void DoSomethingImpl()
{
// Do actual work.
}
};
Derived2 也是如此。
我知道有一些与虚拟方法相关的开销(可能微不足道,但仍然如此),并且受保护的变量可能不适合封装,或者它可能被遗忘并未初始化。所以我的问题基本上是,其中哪一个是可取的,为什么,或者我应该完全避免这种情况并尝试以不同的方式处理它?
注意:我的实际代码有点复杂。我还没有实际测试过这段代码是否有效,如果不正确请见谅。
*当我说接口时,我的意思是一个只包含纯虚函数的类。