2016-12-02 141 views
1
#include <iostream> 
#include<cstdio> 
#include<typeinfo> 

using std::cout; 
using std::endl; 

class foo; 
class bar 
{ 
    public: 
     bar() 
     { 
     } 
     bar(void (*getNextValue)(void)):memberFunctionPointer(getNextValue) 
     { 
     } 
     void calltoderivedslass() 
     { 
      // *memberFunctionPointer(); 
      ((bar*)this)->bar::memberFunctionPointer; 
     } 
     void (foo::*memberFunctionPointer)(); 
}; 

class foo : public bar 
{ 
    public: 
     foo():bar(static_cast<foo::*memberFunctionPointer>(&foo::hello)) 
     { 
     } 
     void hello() 
     { 
      printf("Hello \n\n"); 
     } 
}; 
void byebye() 
{ 
    cout << "bye" << endl; 
} 
int main() 
{ 
    foo testfoo; 
    //((testfoo).*(testfoo.memberFunctionPointer))(); 
    return 0; 
} 

错误:传递函数作为构造参数到基类的构造而初始化

classname.cpp: In constructor "bar::bar(void (*)())": 
classname.cpp:15:68: error: cannot convert "void (*)()" to "void (foo::*)()" in initialization 
classname.cpp: In constructor "foo::foo()": 
classname.cpp:29:25: error: expected type-specifier 
classname.cpp:29:25: error: expected ">" 
classname.cpp:29:25: error: expected "(" 
classname.cpp:29:30: error: expected unqualified-id before "*" token 
classname.cpp:31:2: error: expected "{" at end of input 

期望:

我要初始化的基类函数指针初始化它指向派生类成员函数。我想在创建派生类的对象时进行初始化。从基类我想使用获得的函数指针调用派生类函数。

在此先感谢所有人。

+1

如果使用OOP正确的,没有必要使用函数指针.. 。考虑一下程序员谁需要维护你的代码.. –

+0

是啊,有要求使用函数指针。 当数据库读取发生某种错误时,必须调用一个回调函数,所以我需要函数指针,而不是难以维护代码。谢谢:) –

回答

0

您的bar构造函数是错误的。

bar(void (*getNextValue)(void))不期望的foo并且因此初始化bar::memberFunctionPointer的函数的成员函数的指针的构造是不可能的getNextValue类型。

您需要将构造函数中的参数更改为void (foo::*getNextValue)(void)才能编译。

但整体设计并没有真正似乎我的权利......所以我觉得@wasthishelpful的答案是更有帮助;-)

+0

该错误已修复但仍然此错误 classname.cpp:在构造函数中的:: foo() classname.cpp:29:25:错误:预期的类型说明符 classname.cpp: 29:25:错误:预计? classname.cpp:29:25:错误:预计? classname.cpp:29:30:错误:预期的非限定ID之前的标记 classname.cpp: 31:2:错误:预期{A在输入 –

+0

末请解决您的双引号.... –

+0

西蒙 - 克雷默 这是我的派生类的构造函数我试图函数指针传递给基类构造函数 FOO ():bar(static_cast (&foo :: hello)) 如果我错了,请纠正我。 –

2

貌似虚拟方法对我说:

class bar 
{ 
    public: 
     bar() 
     { 
     } 
     void calltoderivedslass() 
     { 
      this->hello(); 
     } 
     virtual void hello() = 0; 
}; 

class foo : public bar 
{ 
    public: 
     foo() 
     { 
     } 
     void hello() override 
     { 
      printf("Hello \n\n"); 
     } 
}; 

的其他方式,可能是使用奇异递归模板模式(CRTP)来实现的静态多态性:

template<typename T> 
class bar 
{ 
    public: 
     bar() 
     { 
     } 
     void calltoderivedslass() 
     { 
      static_cast<T*>(this)->hello(); 
     } 
}; 

class foo : public bar<foo> 
{ 
    public: 
     foo() 
     { 
     } 
     void hello() 
     { 
      printf("Hello \n\n"); 
     } 
}; 

如果你真的想保留成员函数的指针,你可以考虑std::function绑定到this

class bar 
{ 
    public: 
     bar() 
     { 
     } 
     template<typename F> 
     bar(F&& getNextValue):memberFunctionPointer(std::forward<F>(getNextValue)) 
     { 
     } 
     void calltoderivedslass() 
     { 
      this->memberFunctionPointer(); 
     } 
     std::function<void()> memberFunctionPointer; 
}; 

class foo : public bar 
{ 
    public: 
     foo():bar(std::bind(&foo::hello, this)) 
     { 
     } 
     void hello() 
     { 
      printf("Hello \n\n"); 
     } 
}; 

更宽广的使用我猜:

void byebye() 
{ 
    cout << "bye" << endl; 
} 
int main() 
{ 
    bar testbar(byebye); 
    testbar.calltoderivedslass(); // not a derived class, but it works 
    return 0; 
} 
+0

谢谢你的回答,当我使用你的代码时,我得到的错误如下, –

+0

@KiruthikaPalanivelu没有“错误如下”^^无论如何,你添加了'#include '的std :: function'? – wasthishelpful

+0

感谢您的回答,当我使用您的代码时,我收到如下错误, 错误:预期â,â或ÄÂ前&&令牌 错误:âfunctionâ在命名空间âstdâ没有指定类型 在构造函数中ABAR ::条(六): 错误:类âbarâ没有名为âmemberFunctionPointerâ任何领域 错误:âforwardâ不是âstdâ成员之前预期基本表达式A>令牌 错误: 错误âgetNextValueâ并没有在此范围 宣布在成员函数避免吧:: calltoderivedslass()A: 错误:ACLASS巴拉没有名为âmemberFunctionPointerâ –

相关问题