【问题标题】:defining functions on-the-fly in C++在 C++ 中动态定义函数
【发布时间】:2013-02-23 09:40:10
【问题描述】:

在 C++ 中,是否可以在另一个(除了依赖关系之外不相关)类的函数中实现一个类的函数?我正在寻找的行为可以使用在匿名内部类中实现的抽象方法和/或接口在 Java 中实现,如下所示:

Interface IFoo{

public void doFoo();

}

Class Bar {
private IFoo impl;
public Bar(IFoo implArg){
    impl = implArg;
}


}
static void main(String[] args) {
Bar myBar = new Bar(new IFoo(){
    @Override
    public void doFoo(){
        System.out.println("hello foo impl!");
    }
});
}

在 C++ 中可以实现同样的效果吗?如果可以,如何实现?我想到的用例是动态定义规则,如下所示:

AbstractRule.h

#ifndef _ABSTRACT_RULE_H_
#define _ABSTRACT_RULE_H_

#include <stdio.h>

class AbstractRule{
private:

public:
AbstractRule();
~AbstractRule();
void enforceAbstractRule();
};

#endif

AbstractRule.cpp

#include "AbstractRule.h"
AbstractRule::AbstractRule(){
}
AbstractRule::~AbstractRule(){
}

void AbstractRule::enforceAbstractRule(){
printf("placeholder impl of enforceRule-- should not see this in production");
}

Main.cpp

#include "AbstractRule.h"

int main(int argc, char** argv){
AbstractRule myRule;
//do something here so that myRule.enforceAbstractRule() call prints "enforced 
    //myRule!"
myRule.enforceAbstractRule();
}

问题是,我需要在 'do something here...' 评论处做什么才能达到预期的效果?

【问题讨论】:

  • Lambdas 适用于动态函数。此外,您的包含保护名称是保留的。
  • 我听说过 lambda,但从未使用过它们——您能否提供一个示例用法或指向一个好的综合教程的链接?
  • C++/CLI 还没有 lambda。为什么这个问题还是被标记为c++-cli
  • 对我来说,这看起来像是 XY 问题的一个实例。你真正想要完成什么?
  • @CCJ,将两个整数相乘的函数对象是auto f = [](int a, int b) {return a * b;};。有很多很好的资源很容易用这个词在谷歌上搜索。

标签: c++ interface c++-cli implementation


【解决方案1】:

Java 有一个叫做“无名类”的东西,这是您的示例使用的 - 请注意,您的“概念”有点“错误”,因为您实际上并没有“即时”声明一个函数,而是声明了一个新的“在飞行中”上课。

在 C++ 中,所有类都必须有一个名称 [1]。

所以,对于你想做的事情,你需要声明一个扩展基类的类:

class MyRule : public Rule
{
   void enforceRule();
};


void MyRule::enforceRule()
{
   ... stuff goes here ... 
}

您当然也可以将声明 inline 放在类声明中。但是要让它可以使用,你需要给它一个名字。

现在,你的主要将有:

MyRule myRule;

[或者,更可能的是,您调用一个工厂函数来选择“正确”的规则类,创建一个新对象,并返回一个指向该对象的指针]

[1] 并非总是如此,但对于这种特殊用途,您确实需要一个类名。

【讨论】:

  • 嗯,好吧,可以完成这项工作。不过,在这种情况下,我想在 AbstractRule 类虚拟中标记 enforceRule() 和 ~AbstractRule(),对吧?
  • 是的,如果你想使用工厂,当然可以。但总的来说,如果您打算继承和覆盖函数,这是设计事物的好方法。
  • 就是这样。 java 无名类定义是语法糖,最终该类将被赋予一个生成的名称。在 C++ 中,需要简单地隐藏类定义以获得类似的效果。
  • 请注意,它有一个棘手的方面,即当匿名类定义引用来自定义发生范围的值时。您的示例没有该功能,但有可能是 iirc。解决方案是将这些值作为类构造函数的参数,或者将它们作为模板参数,在这种情况下,隐藏类必须是模板。
【解决方案2】:

如果您只对可内联定义的小函数感兴趣,您将需要查看 C++11 中添加的 std::function 和 lambda 支持。如果这不是一个选项,您也许可以使用一些 boost 库,但您可能需要定义一些命名的一次性类。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-29
    • 2014-07-03
    相关资源
    最近更新 更多