在C++中不可能声明静态虚函数,也不能将非静态函数强制转换为C样式函数指针.
现在,我有一个简单的ol'C SDK,它大量使用函数指针.
我必须用几个函数指针填充一个结构.我计划使用一个带有一堆静态纯虚方法的抽象类,并在派生类中重新定义它们并用它们填充结构.直到那时我才意识到在C++中不允许使用静态虚拟.
此C SDKs函数签名也没有userData参数.
有什么好的选择吗?我能想到的最好的方法是在每个派生类中定义一些纯虚方法GetFuncA(),GetFuncB(),...和一些静态成员FuncA()/ FuncB(),它们将由GetFuncX()返回.然后抽象类中的函数将调用这些函数来获取指针并填充结构.
编辑 回答John Dibling,能够做到这一点真是太好了:
class Base
{
FillPointers() { myStruct.funA = myFunA; myStruct.funB = myFunB; ...}
private:
CStruct myStruct;
static virtual myFunA(...) = 0;
static virtual myFunB(...) = 0;
};
class Derived1 : public Base
{
Derived1() { FillPointers(); }
static virtual myFunA(...) {...};
static virtual myFunB(...) {...};
};
class Derived2 : public Base
{
Derived2() { FillPointers(); }
static virtual myFunA(...) {...};
static virtual myFunB(...) {...};
};
int main()
{
Derived1 d1; …Run Code Online (Sandbox Code Playgroud) 考虑以下typedef:
typedef int (*f1)(float);
typedef f1 (*f2)(double);
typedef f2 (*f3)(int);
Run Code Online (Sandbox Code Playgroud)
f2是一个返回函数指针的函数.与...相同f3,但函数的类型,f3返回的指针是f2.如何在f3没有typedef的情况下定义?我知道typedef是更清晰,更容易理解的定义方式f3.但是,我的目的是更好地理解C语法.
我有一个包含回调的变量,默认情况下它的值应为null.但是这种语法似乎不起作用.
var callback1 : () -> Unit = null
var callback2 : ((a) -> c, b) -> Unit = null
Run Code Online (Sandbox Code Playgroud)
我目前的解决方案是确保回调具有默认实现.
var callback1 : () -> Unit = { }
var callback2 : ((a) -> c, b) -> Unit = { a, b -> }
Run Code Online (Sandbox Code Playgroud)
但是,这使得很难检查回调是否已设置,并且可能默认实现是否需要付出一定的代价(是这样吗?).如何在Kotlin中为函数类型变量赋值空值?
我有以下代码。有一个函数需要两个int32。然后,我将指针指向它,并将其强制转换为需要三个int8的函数并进行调用。我预计会出现运行时错误,但程序运行正常。为什么这样可能?
main.cpp:
#include <iostream>
using namespace std;
void f(int32_t a, int32_t b) {
cout << a << " " << b << endl;
}
int main() {
cout << typeid(&f).name() << endl;
auto g = reinterpret_cast<void(*)(int8_t, int8_t, int8_t)>(&f);
cout << typeid(g).name() << endl;
g(10, 20, 30);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
PFviiE
PFvaaaE
10 20
Run Code Online (Sandbox Code Playgroud)
如我所见,第一个函数的签名需要两个整数,第二个函数需要三个字符。Char小于int,我想知道为什么a和b仍然等于10和20。
C++如何处理与具有默认参数的函数相关的函数指针?
如果我有:
void foo(int i, float f = 0.0f);
void bar(int i, float f);
void (*func_ptr1)(int);
void (*func_ptr2)(int, float);
void (*func_ptr3)(int, float = 10.0f);
Run Code Online (Sandbox Code Playgroud)
哪个函数指针可以用于哪个函数?
我想将函数值作为模板参数传递给函数.目前我设法做的最好的是:
template< typename F, F f >
void pass()
{
...
}
Run Code Online (Sandbox Code Playgroud)
...使用的:
pass< decltype(&func), &func >();
Run Code Online (Sandbox Code Playgroud)
我真正想要的是:
pass< &func >();
Run Code Online (Sandbox Code Playgroud)
有没有办法在没有宏的情况下实现这个目标?基本上同时传递类型和值?编译器显然拥有所需的所有信息......
解决方案必须使用变量参数和返回类型.函数值在编译时使用,因此不能作为参数传递.
欢迎使用C++ 11解决方案.
编辑:用例 - 我在编译时生成绑定,我需要为每个传递的函数创建一个C++函数.这段代码的用例看起来(简化)或多或少像这样:
template < typename F, F f >
int function_wrapper( lua_State* L )
{
return dispatcher<typename return_type<F>::type>::call( L, 1, f );
}
void register_native_function( lua_Function f, const char* name )
{
// binding call using pure C function f
}
template < typename F, F f >
void register_function( const …Run Code Online (Sandbox Code Playgroud) 我正在努力在C++中实现一个反射机制.我的代码中的所有对象都是Object的子类(我自己的泛型类型),它包含类型为Class的静态成员数据.
class Class{
public:
Class(const std::string &n, Object *(*c)());
protected:
std::string name; // Name for subclass
Object *(*create)(); // Pointer to creation function for subclass
};
Run Code Online (Sandbox Code Playgroud)
对于具有静态Class成员数据的Object的任何子类,我希望能够使用指向该子类的构造函数的指针初始化'create'.
我找到了有趣的东西.错误消息说明了一切.在获取非静态成员函数的地址时不允许使用括号的原因是什么?我在gcc 4.3.4上编译了它.
#include <iostream>
class myfoo{
public:
int foo(int number){
return (number*10);
}
};
int main (int argc, char * const argv[]) {
int (myfoo::*fPtr)(int) = NULL;
fPtr = &(myfoo::foo); // main.cpp:14
return 0;
}
Run Code Online (Sandbox Code Playgroud)
错误:main.cpp:14:错误:ISO C++禁止获取非限定或带括号的非静态成员函数的地址,以形成指向成员函数的指针.说'&myfoo :: foo'
我认为如果我为函数指针创建了一个typedef会更容易使用函数指针,但我似乎让自己绊倒了一些语法或用法或类似于函数指针的typedef,我可以使用一些帮助.
我有
int foo(int i){ return i + 1;}
typedef <???> g;
int hvar;
hvar = g(3)
Run Code Online (Sandbox Code Playgroud)
这基本上就是我想要完成的事情,我是一个相当新的C程序员,这让我太过分了.有什么替代<???>?
在C++中实现多态行为时,可以使用纯虚方法,也可以使用函数指针(或函子).例如,异步回调可以通过以下方式实现:
class Callback
{
public:
Callback();
~Callback();
void go();
protected:
virtual void doGo() = 0;
};
//Constructor and Destructor
void Callback::go()
{
doGo();
}
Run Code Online (Sandbox Code Playgroud)
因此,要在此处使用回调,您需要覆盖doGo()方法以调用您想要的任何函数
typedef void (CallbackFunction*)(void*)
class Callback
{
public:
Callback(CallbackFunction* func, void* param);
~Callback();
void go();
private:
CallbackFunction* iFunc;
void* iParam;
};
Callback::Callback(CallbackFunction* func, void* param) :
iFunc(func),
iParam(param)
{}
//Destructor
void go()
{
(*iFunc)(iParam);
}
Run Code Online (Sandbox Code Playgroud)
要在此处使用回调方法,您需要创建一个由Callback对象调用的函数指针.
[这是我(Andreas)在问题中添加的; 它不是由原始海报写的]
template <typename T>
class Callback
{
public:
Callback() {}
~Callback() {}
void go() {
T …Run Code Online (Sandbox Code Playgroud)