修改C ++中现有函数的任何技巧或窍门?

时间:2018-01-30 04:17:21

标签: c++ signals-slots qt-signals

在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一样的信号和插槽系统。虽然我不知道如何自己做这样的事情。

感谢您的阅读;我希望你有一些建议。

4 个答案:

答案 0 :(得分:5)

好吧,如果你认识到JavaScript函数的哪个特性使这成为可能,那么在C ++中做同样的事情并不难。在JavaScript函数中也有闭包,C ++中的常规函数​​没有。但是C ++ lambda属于闭包类型。如果一个人将bunny定义为既可以包含闭包类型的对象又可以重新分配的东西,那么你就可以了。{/ p>

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();

答案 1 :(得分:1)

你可以使用仿函数。

#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;
}

答案 2 :(得分:1)

假设目标是允许调用代码扩展程序的功能,超出初始代码提供的功能,我可能会使用一个用户可更新的仿函数对象数组,如下所示:

#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;
}

答案 3 :(得分: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(),请将其删除。