【问题标题】:Passing a polymorphic function as a parameter to another function in C将多态函数作为参数传递给 C 中的另一个函数
【发布时间】:2023-04-04 03:55:02
【问题描述】:

关于这个问题,我只在 C 中工作。

我有两个函数原型:

int pkg_permserver(const char *service, const char *protocol, int backlog, void (*errlog) (char *msg))

int pkg_permserver_ip(const char *ipOrHostname, const char *service, const char *protocol, int backlog, void (*errlog)(char *msg))

以及以下代码段:

int test_permserv(char *port) {
    int return_val;
    int num_port;
    char *chr_port;
    int nr_test_passed=0;
    chr_port = (char *) bu_malloc(8 * sizeof( char), "port string");

    printf("TESTING  PKG_PERMSERVER.....\n PORT PARAMETER TEST: \n");

    printf("TESTING VALID PORT...\n");
    return_val = pkg_permserver(port ,"tcp", 0, 0);
    display(return_val,1,&nr_test_passed);

    printf("TESTING INVALID PORT...\n");
    num_port = -1;
    sprintf(chr_port, "%d", num_port);
    return_val = pkg_permserver(chr_port ,"tcp", 0, 0);
    display(return_val,0,&nr_test_passed);
}

我正在编写一个测试单元。我需要为函数的每个参数测试每种情况(有效/无效)。

我无法修改上述功能。 pkg_permserver 和 pkg_permserver_ip 具有完全相同的参数,除了 pkg_permserver_ip 还具有 IpOrHostname。

如果我要编写另一个函数“test_permserver_ip”,我不想复制 - 粘贴来自 test_permserver 的部分(因为参数相同)。

我想到的是 int test_permserver(char * port, int which_function);

我想避免为 test_permserver_ip 复制相同的代码(对于与 test_permserver 相同的参数) pkg_permserver_ip 的测试函数还没写。

这是上面两个函数的代码:

int pkg_permserver(const char *service, const char *protocol, int backlog, void (*errlog) (char *msg))
{
    struct in_addr iface;
    iface.s_addr = INADDR_ANY;
    return _pkg_permserver_impl(iface, service, protocol, backlog, errlog);
}


int
pkg_permserver_ip(const char *ipOrHostname, const char *service, const char *protocol, int backlog, void (*errlog)(char *msg))
{
    struct hostent* host;
    struct in_addr iface;
    /* if ipOrHostname starts with a number, it's an IP */
    if (ipOrHostname) {
    if (ipOrHostname[0] >= '0' && ipOrHostname[0] <= '9') {
        iface.s_addr = inet_addr(ipOrHostname);
    } else {
        /* XXX gethostbyname is deprecated on Windows */
        host = gethostbyname(ipOrHostname);
        iface = *(struct in_addr*)host->h_addr;
    }
    return _pkg_permserver_impl(iface, service, protocol, backlog, errlog);
    } else {
    _pkg_perror(errlog, "pkg: ipOrHostname cannot be NULL");
    return -1;
    }
}

【问题讨论】:

  • 在完成“专门的工作”之后,您是否考虑过从 pkg_permserver_ip 调用 pkg_permserver?而且我认为将函数指针转换为 void 指针是行不通的……实际上,我很确定它不会。
  • 但是您打算将什么作为额外参数传递给pkg_permserver_ip?如果你必须准备那个额外的参数,那意味着代码不是完整的复制粘贴。
  • 您使用不同的端口(arg1)调用 pkg_permserver() 两次。 pkg_permserver_ip() 在哪里??

标签: c parameter-passing parametric-polymorphism


【解决方案1】:

正如 ATaylor 所说,只需从两个函数中提取共同的东西并得到类似的东西

int common_stuff_for_permserver(... all common params ...)
{
  ....
}

int pkg_permserver(...)
{
      /// nothing to add here
      return common_stuff_for_permserver( ... all params ... );
}

int pkg_permserver_ip(...)
{
      /// check for errors from common stuff
      if(!common_stuff_for_permserver( ... all params ... )) { return 0; }

      /// ip-specific stuff
      ...
}

如果您不知道如何提取公共部分,请为这两个函数发布更多代码,我们会考虑一下。

【讨论】:

  • 我认为解决方案比看起来简单。 pkg_permserver 和 pkg_permserver_ip 都调用 _pkg_permserver_impl(iface, service, protocol, backlog, errlog);所以,如果我测试 pkg_permserver 的每个参数,然后只测试 pkg_permserver_ip 的 ipOrhostname 参数,它仍然是一个完整的测试
【解决方案2】:

强制转换函数指针是绝对禁忌。请改用接受指向结构的指针的中间函数类型。或者以 union-type-tag 作为第一个成员的 union 参数。

中间函数(每个“真实”函数一个)只需从结构中提取正确的参数并将它们传递给正确的函数。

【讨论】:

  • 两个函数调用相同的事实 _pkg_permserver_impl(iface, service, protocol, backlog, errlog);简化事情,我将测试 pkg_permserver 的每个参数,然后对于 pkg_permserver_ip 只测试 ipOrHostname 参数
猜你喜欢
  • 1970-01-01
  • 2017-08-07
  • 2013-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-16
相关资源
最近更新 更多