在 C++ 中修改现有函数的任何技术或技巧?
Any techniques or tricks to modifying existing functions in C++?
在 JavaScript 内,您可以完成这样的事情:
function bunny() { alert("The bunny jumped."); }
var oldBunny = bunny;
function bunny() {
oldBunny();
alert("The bunny also ran.");
}
bunny(); // The bunny Jumped. The bunny also ran.
正如你所看到的,旧的 "bunny" 函数通过复制到一个变量来附加代码,然后用相同的名称重新创建函数。原函数拷贝运行,新代码也运行
我希望在 C++ 中复制类似的机制。
现在,在您崩溃并开始解释静态语言和动态语言之间的区别之前,我明白了。我不是在寻找与所提供的相同的东西,但我确实想要类似的东西。
此外,我这样做并不是为了修改现有代码;我希望格式化我自己的源代码,以允许其他用户利用这种机制。
我的第一个想法可能是在代码中设置各种宏,以后可以由其他文件修改。
另一个想法是创建一个类似于 QT 的信号和插槽系统。虽然我自己也不知道怎么做。
感谢您的阅读;希望大家多提建议。
你可以使用仿函数。
#include <iostream>
#include <string>
class Base
{
public:
virtual std::string operator ()()
{
return "Base call";
}
virtual ~Base() {}
};
class Derived : public Base
{
public:
virtual std::string operator()()
{
return "Wrapper: " + Base::operator()();
}
};
int main()
{
Base* pFun = new Base;
std::cout << "Now check Base: " << (*pFun)() << std::endl;
delete pFun;
pFun = new Derived;
std::cout << "Now check Derived: " << (*pFun)() << std::endl;
return 0;
}
void bunny()
{
cout << "The bunny jumped." << endl;
}
void oldBunny()
{
bunny();
}
void newBunny()
{
bunny();
cout << "The bunny also ran." << endl;
}
#define bunny newBunny
int main()
{
bunny();
return 0;
}
如果不需要oldBunny()
,直接删除即可。
假设目标是允许调用代码扩展程序的功能,超出初始代码提供的功能,我可能会使用用户可更新的仿函数对象数组,如下所示:
#include <iostream>
#include <memory>
class Function
{
public:
virtual void Call() = 0;
};
typedef std::shared_ptr<Function> FunctionSharedPointer;
class OldBunny : public Function
{
public:
virtual void Call()
{
std::cout << "The bunny jumped." << std::endl;
}
};
class NewBunny : public Function
{
public:
NewBunny(FunctionSharedPointer oldFunction) : _oldFunction(oldFunction) {/* empty */}
virtual void Call()
{
_oldFunction->Call();
std::cout << "The bunny also ran." << std::endl;
}
private:
FunctionSharedPointer _oldFunction;
};
enum {
FUNCTION_BUNNY,
// other functions could be declared here later...
NUM_FUNCTIONS
};
// Our table of functions that the user can Call() if he wants to
static FunctionSharedPointer _functionTable[NUM_FUNCTIONS];
// Wrapper function, just to keep users from accessing our table directly,
// in case we ever want to change it to something else
void CallFunction(int whichFunction)
{
_functionTable[whichFunction]->Call();
}
// Another wrapper function
void SetFunction(int whichFunction, FunctionSharedPointer newFunctionDefinition)
{
_functionTable[whichFunction] = newFunctionDefinition;
}
// And another
FunctionSharedPointer GetFunction(int whichFunction)
{
return _functionTable[whichFunction];
}
int main(int argc, char ** argv)
{
// Our default function values get set here
SetFunction(FUNCTION_BUNNY, std::make_shared<OldBunny>());
std::cout << "before:" << std::endl;
CallFunction(FUNCTION_BUNNY);
// Now let's update an entry in our function table to do something different!
FunctionSharedPointer op = GetFunction(FUNCTION_BUNNY);
FunctionSharedPointer np = std::make_shared<NewBunny>(op);
SetFunction(FUNCTION_BUNNY, np);
std::cout << "after:" << std::endl;
CallFunction(FUNCTION_BUNNY);
return 0;
}
好吧,如果您认识到 JavaScript 函数的哪个特性使这成为可能,那么在 C++ 中做同样的事情就不难了。在 JavaScript 中,函数也有闭包,这是 C++ 中的常规函数所没有的。但是 C++ lambda 是闭包类型的。如果将 bunny
定义为既可以容纳闭包类型的对象又可以重新分配的对象,那么您就已经准备好了。
C++ 标准库为此提供了一个不错的默认选择,形式为 std::function
。我们可以将您原来的 JavaScript 重写如下:
std::function<void()> bunny = [] {
std::cout << "The bunny jumped.\n";
};
auto oldBunny = std::move(bunny);
bunny = [oldBunny] {
oldBunny();
std::cout << "The bunny also ran.\n";
};
bunny();
在 JavaScript 内,您可以完成这样的事情:
function bunny() { alert("The bunny jumped."); }
var oldBunny = bunny;
function bunny() {
oldBunny();
alert("The bunny also ran.");
}
bunny(); // The bunny Jumped. The bunny also ran.
正如你所看到的,旧的 "bunny" 函数通过复制到一个变量来附加代码,然后用相同的名称重新创建函数。原函数拷贝运行,新代码也运行
我希望在 C++ 中复制类似的机制。
现在,在您崩溃并开始解释静态语言和动态语言之间的区别之前,我明白了。我不是在寻找与所提供的相同的东西,但我确实想要类似的东西。
此外,我这样做并不是为了修改现有代码;我希望格式化我自己的源代码,以允许其他用户利用这种机制。
我的第一个想法可能是在代码中设置各种宏,以后可以由其他文件修改。
另一个想法是创建一个类似于 QT 的信号和插槽系统。虽然我自己也不知道怎么做。
感谢您的阅读;希望大家多提建议。
你可以使用仿函数。
#include <iostream>
#include <string>
class Base
{
public:
virtual std::string operator ()()
{
return "Base call";
}
virtual ~Base() {}
};
class Derived : public Base
{
public:
virtual std::string operator()()
{
return "Wrapper: " + Base::operator()();
}
};
int main()
{
Base* pFun = new Base;
std::cout << "Now check Base: " << (*pFun)() << std::endl;
delete pFun;
pFun = new Derived;
std::cout << "Now check Derived: " << (*pFun)() << std::endl;
return 0;
}
void bunny()
{
cout << "The bunny jumped." << endl;
}
void oldBunny()
{
bunny();
}
void newBunny()
{
bunny();
cout << "The bunny also ran." << endl;
}
#define bunny newBunny
int main()
{
bunny();
return 0;
}
如果不需要oldBunny()
,直接删除即可。
假设目标是允许调用代码扩展程序的功能,超出初始代码提供的功能,我可能会使用用户可更新的仿函数对象数组,如下所示:
#include <iostream>
#include <memory>
class Function
{
public:
virtual void Call() = 0;
};
typedef std::shared_ptr<Function> FunctionSharedPointer;
class OldBunny : public Function
{
public:
virtual void Call()
{
std::cout << "The bunny jumped." << std::endl;
}
};
class NewBunny : public Function
{
public:
NewBunny(FunctionSharedPointer oldFunction) : _oldFunction(oldFunction) {/* empty */}
virtual void Call()
{
_oldFunction->Call();
std::cout << "The bunny also ran." << std::endl;
}
private:
FunctionSharedPointer _oldFunction;
};
enum {
FUNCTION_BUNNY,
// other functions could be declared here later...
NUM_FUNCTIONS
};
// Our table of functions that the user can Call() if he wants to
static FunctionSharedPointer _functionTable[NUM_FUNCTIONS];
// Wrapper function, just to keep users from accessing our table directly,
// in case we ever want to change it to something else
void CallFunction(int whichFunction)
{
_functionTable[whichFunction]->Call();
}
// Another wrapper function
void SetFunction(int whichFunction, FunctionSharedPointer newFunctionDefinition)
{
_functionTable[whichFunction] = newFunctionDefinition;
}
// And another
FunctionSharedPointer GetFunction(int whichFunction)
{
return _functionTable[whichFunction];
}
int main(int argc, char ** argv)
{
// Our default function values get set here
SetFunction(FUNCTION_BUNNY, std::make_shared<OldBunny>());
std::cout << "before:" << std::endl;
CallFunction(FUNCTION_BUNNY);
// Now let's update an entry in our function table to do something different!
FunctionSharedPointer op = GetFunction(FUNCTION_BUNNY);
FunctionSharedPointer np = std::make_shared<NewBunny>(op);
SetFunction(FUNCTION_BUNNY, np);
std::cout << "after:" << std::endl;
CallFunction(FUNCTION_BUNNY);
return 0;
}
好吧,如果您认识到 JavaScript 函数的哪个特性使这成为可能,那么在 C++ 中做同样的事情就不难了。在 JavaScript 中,函数也有闭包,这是 C++ 中的常规函数所没有的。但是 C++ lambda 是闭包类型的。如果将 bunny
定义为既可以容纳闭包类型的对象又可以重新分配的对象,那么您就已经准备好了。
C++ 标准库为此提供了一个不错的默认选择,形式为 std::function
。我们可以将您原来的 JavaScript 重写如下:
std::function<void()> bunny = [] {
std::cout << "The bunny jumped.\n";
};
auto oldBunny = std::move(bunny);
bunny = [oldBunny] {
oldBunny();
std::cout << "The bunny also ran.\n";
};
bunny();