在以下极为简短的类中,我想在基础中定义一个方法(ProcessLines),它将迭代一组数据库记录,将每个记录作为参数传递给仅在子类中定义的函数。显然,Base是一个永远不会自己实例化的虚拟类。
Class Base {
public:
typedef ProcLineFunc( Long *Line );
void ProcessLines( ProcLineFunc pf);
}
Class Child{
void DoWork( Long *Line) { //do something}
}
我不确定如何实现这一点。如果我在子代中重新声明ProcessLines并且只调用父方法,则会得到相同的错误消息,就好像我在创建子代码的代码中调用ProcessLines一样。
Child c(//something);
c.ProcessLines(c.DoWork);
给我一个编译器消息:
[BCC32错误] main.cpp(67):E2034无法将'bool(*(_ enclosure)(long *))(long )'>转换为'int()(long * )“
完整的解析器上下文
main.cpp(56):class Add2Chan
main.cpp(78):实例化的决定:bool Add2Chan :: ProcessByLines()
---重置解析器上下文以进行实例化...
main.cpp(67):解析:bool Add2Chan :: ProcessByLines()
我对c ++很新,E2034的错误信息吓坏了我。
请帮忙。我使用了一个typedef,这样我就可以在我的子类中多次调用ProcessLines,然后传递不同的函数。
答案 0 :(得分:4)
通常情况下,您会使用受保护的纯虚函数执行此类操作:
class Base {
public:
ProcessLines() {
//Logic to process lines here, obviously psuedo-code
while(moreLines) {
ProcessLine(line);
}
}
protected:
virtual void ProcessLine(const Line& line) = 0;
}
class Child : public Base {
protected:
void ProcessLine(const Line& line) { //Logic to process the line for this type }
};
class DifferentChild : public Base {
protected:
void ProcessLine(const Line& line) { //Logic to process the line for DifferentChild }
};
我认为这是你正在寻找的那种东西。在我看来,你试图以奇怪的方式实现多态,但这是在C ++中实现它的常规方法。
答案 1 :(得分:1)
不使用指向函数的指针,而是使用指向对象的指针。接受你的函数将被称为DoWork
的限制而不是其他任何限制,并且每个类中只能有一个这样的函数。这不是一个很糟糕的限制。在类(称为接口)中声明(纯虚拟)函数,并从中派生类(它们被称为实现接口)。
struct DoingWork
{
virtual void DoWork(long *Line) = 0; // does some work on a list
};
struct DoingGreatWork: DoingWork
{
virtual void DoWork(long *Line) {printf("Great work\n");}
};
struct DoingSlightWork: DoingWork
{
virtual void DoWork(long *Line) {printf("Slight work\n");}
};
使用此示例:
class Base {
public:
void ProcessLines(DoingWork& object) {
//Logic to process lines here
while(moreLines) {
object.DoWork(line);
}
}
};
class Whatever // no need to derive from Base
{
void DoStuff()
{
Base object;
object.ProcessLines(DoingGreatWork());
object.ProcessLines(DoingSlightWork());
}
}
如果工作对象必须能够访问调用对象,请按以下方式初始化它们:
class Whatever // no need to derive from Base
{
struct DoingElaborateWork: DoingWork
{
Whatever& caller;
DoingElaborateWork(Whatever& caller): caller(caller) {}
virtual void DoWork(long *Line)
{
printf("Doing work requested by %s\n", caller.name());
}
};
void DoStuff()
{
Base object;
object.ProcessLines(DoingElaborateWork(*this));
}
const char* name() {return "Whatever";}
}
P.S。他们说“在C ++ 03中functions are second-class citizens”,因为你不能用你可以用对象做的函数(比如我提供的这个解决方案)。我听说在C ++ 11中功能有很大的改进,但我不确定细节。
答案 2 :(得分:0)
由于您是在C ++ Builder中执行此操作,因此您可以利用其__closure
扩展来完全按照您的要求执行(VCL的某些部分会针对自己的回调执行此操作):
class Base
{
public:
virtual ~Base() {}
typedef void (__closure *ProcLineFunc)( Long *Line );
void ProcessLines( ProcLineFunc pf);
};
class Child : public Base
{
public:
void DoWork( Long *Line) { //do something}
};
Child c(...);
c.ProcessLines(c.DoWork);