在C++中修改现有函数的技巧或技巧?

在C++中修改现有函数的技巧或技巧?,c++,signals-slots,qt-signals,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. #include <iostream> #include

在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.
#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;
}
可以看到,旧的bunny函数通过复制到变量,然后用相同的名称重新创建函数,从而将代码附加到它。原始函数的副本将运行,新代码也将运行

我希望在C++中复制类似的机械。p> 现在,在你崩溃并开始解释静态和动态语言之间的差异之前,我明白了。我不是在寻找与所提供的东西完全相同的东西,但我确实希望得到类似的东西

此外,我并不是试图这样做来修改现有的代码;我希望格式化我自己的源代码,以允许其他用户利用这种机制

我最初的想法之一是在代码中设置各种宏,这些宏以后可以被其他文件修改

另一个想法是创建一个信号和插槽系统,如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;
}
你可以使用函子

#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;
}
如果你不需要老兔子,就把它拿走


如果您不需要oldBunny,只需删除它。

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

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

假设目标是允许调用代码将程序的功能扩展到初始代码提供的功能之外,我可能会使用用户可更新的functor对象数组,如下所示:

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.
#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++ LAMBDAS是一个封闭类型。如果有人将bunny定义为既可以保存闭包类型的对象,又可以被重新分配的对象,那么就一切就绪

C++标准库提供了一个很好的默认选择,以STD::Fuffic的形式。我们可以按如下方式重新编写您的原始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函数的特性使这成为可能,那么在C++中做同样的事情并不太难。在JavaScript函数中也有闭包,C++中的正则函数没有。但是C++ LAMBDAS是一个封闭类型。如果有人将bunny定义为既可以保存闭包类型的对象,又可以被重新分配的对象,那么就一切就绪

C++标准库提供了一个很好的默认选择,以STD::Fuffic的形式。我们可以按如下方式重新编写您的原始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();

在C++中,这是不可能的。对于这样的事情,通常使用继承。你不能使用方法重写技术吗?在C++中,这是不可能的。对于像这样的事情,通常使用继承。你不能使用方法重写技术吗?你展示的代码不是关于functor的,而是关于继承和虚拟函数重写的。这是一个很好的解决方案,但你应该真正使用std::unique_ptr来管理堆分配的对象。这将防止您现在的内存泄漏。您展示的代码不是关于functor,而是关于继承和虚拟函数重写。这是一个很好的解决方案,但您应该真正使用std::unique_ptr来管理堆分配的对象。这将防止您现在的内存泄漏。以这种方式使用宏只是一种手段,会使代码更难阅读和维护。这是实现您声称不可能实现的目标的一种方式。以这种方式使用宏只是一种手段,会使代码更难阅读和维护。这是实现您声称不可能实现的目标的一种方式。