我有2个C++类问题:
第一个问题是:我怎么能这样做,所以我可以将类成员函数作为参数传递给另一个函数?如何运行/调用该函数?我怎么能用类静态函数做同样的事情.通过查看此代码可能更容易理解我的问题:
class DebuggingManager
{
string testLog;
bool test1()
{
// run test & return whether it passed or failed
}
static bool test2()
{
}
// How can I call a member function?
void catalogueTest( string testName, bool DebuggingManager::*nMemberFunction )
{
testLog += "Status of " + testName + ": " + ((*)nMemberFunction()) + "\n";
}
// How can I call a static function?
void catalogueTest( string testName, bool DebuggingManager::*nStaticFunction )
{
testLog += "Status of " + testName + ": " + DebuggingManager::nStaticFunction() + "\n";
}
// how do I pass a member function or a static function as a parameter in another function
bool runTests()
{
catalogueTest( "Test of member functin", test1() );
catalogueTest( "Test of static functin", test2() );
}
};
Run Code Online (Sandbox Code Playgroud)
第二个问题是:如上所述间接调用类成员(或静态)函数是不好(或危险)的做法.我有一种感觉这是非常糟糕的C++实践?
编辑:实施建议 感谢您的回复,我试图实施这个建议,虽然它很多,但这是正确的吗?
// I have a feeling that ParameterList is incorect, would I pass the implicit obj as a parameter or is it done automatically like in normal object function calls?
typedef bool (DebuggingManager::*MemberPointerType)(ParameterList);
void catalogueTest( tstring testName, DebuggingManager* obj, MemberPointerType *nMemberFunction )
{
debugLog += _T("Status of ") + testName + _T(": ") + (obj->*nMemberFunction)() + _T("\r\n");
}
void catalogueStaticTest( tstring testName, bool DebuggingManager::nStaticFunction )
{
debugLog += _T("Status of ") + testName + _T(": ") + nStaticFunction + _T("\r\n");
}
Run Code Online (Sandbox Code Playgroud)
Nic*_*las 13
类的静态成员函数最终与常规函数没有区别.他们真的只是语法糖; 该函数只是包含一个名称Classname::.
非静态成员完全是另一回事.关于非静态成员函数(NSMF),有两件重要的事情需要记住.
首先,每个非静态成员函数都可以访问它们所属的类的非静态成员.即使您可以有两个同一类的对象碰巧存储不同的数据,这也是可能的.如果你有两个std::string对象,它们每个都存储不同的字符串.执行find一个字符串可以在一个字符串中返回找到的结果,而不是另一个字符串.
这是因为每个NSMF都有一个隐式this指针.this不仅指一个类,而且指NSMF运行的实际对象.当你这样做:
std::string aString("data");
aString.find("da");
Run Code Online (Sandbox Code Playgroud)
该find函数采用字符串参数,但它也aString作为其参数this.每次find寻找同类的成员时,都会查看aString数据.
那么让我们来看看您对NSMF的预期召唤:
((*)nMemberFunction())
Run Code Online (Sandbox Code Playgroud)
从它获取this指针的对象在哪里?没有对象,NSMF无法访问对象的非静态成员,因为没有对象可以找到它们.这是不合法的.
因此,关于NSMF的规则#1:您必须使用NSMF所属的类的实际实例(或其派生类)来调用它们.你不能只是拿一个NSMF指针并像函数指针一样调用它; 你必须在这种类型的活动对象上调用它.
规则#2:NSMF指针的语法非常难看.
要定义名为argNSMF指针类型的变量(或参数),请执行以下操作:
ReturnType (ClassName::*arg)(ParameterList);
Run Code Online (Sandbox Code Playgroud)
ReturnType函数的返回类型在哪里,是函数ParameterList采用的参数列表,ClassName是NSMF指针所属的类的名称.
鉴于丑陋,通常最好将其包装在typedef中:
typedef ReturnType (ClassName::*MemberPointerType)(ParameterList);
Run Code Online (Sandbox Code Playgroud)
从而创建了typedef MemberPointerType,它是一个NSMF指针.
给定一个名为的对象object,它是一个类型ClassName,你可以调用成员指针arg,如下所示:
ReturnType value = (object.*arg)(Params);
Run Code Online (Sandbox Code Playgroud)
Params你希望传递的论点在哪里?如果object是指向ClassName而不是引用或值的指针,则object->*arg改为使用.
还有一件事:您必须使用&获取成员指针名称.与函数指针不同,NSMF指针不会自动转换为成员指针.你必须直接问他们.所以,如果ClassName有一个成员叫功能适合以上ReturnType和ParameterList,你将填补arg如下:
arg = &ClassName::Function;
Run Code Online (Sandbox Code Playgroud)
规则#3:非静态成员指针不是指针.是的,他们可以设置为NULL(在技术上,它们可以被设置为0),但它们不是一回事指针.
大多数真正的C和C++编译器都允许您将函数指针强制转换为a void*和back.标准考虑了这种未定义的行为,但这并不是完全未知的.你绝对不能用NSMF指针做到这一点,几乎所有的C++编译器.实际上,这sizeof(MemberPointerType)可能与大小不同void*.
因此,NSMF指针不是常规指针.不要这样对待它们.
| 归档时间: |
|
| 查看次数: |
22214 次 |
| 最近记录: |