相同功能的不同实现(c / c ++)

时间:2017-01-19 16:45:09

标签: c++ c

是否可以为头文件中声明的相同函数提供2个(或更多)不同的实现? 我举一个例子 - 让我们说我们有一个名为common.h的头文件和两个名为src1.csrc2.c的源文件。

COMMON.H

//lots of common function declarations implemented in some file common.c 
int func(int a, int b);

src1.c

#include "common.h"

int func(int a, int b)
{
    return a+b;
}

src2.c

#include "common.h"

int func(int a, int b)
{
    return a*b;
}

让我们说我希望每个源文件都使用其本地版本的func()。是否有可能这样做?

5 个答案:

答案 0 :(得分:5)

是的,但是如果您尝试将主程序与src2src1相关联,则会遇到错误,因为它不知道要使用哪个定义。
标头只是让其他代码对象了解其他对象中可用内容的方法。将标题视为合同。预计合同将被填充一次,而不是零次或多次。如果您同时关联src2int func(int a, int b);,则您实际上已经两次填写string.IsNullOrEmpty合同。

如果您需要在具有相同签名的两个功能之间切换,则可以使用function pointers

答案 1 :(得分:1)

如果您希望每个源文件使用其func的本地实现,并且没有其他模块使用这些函数,您可以从标头中删除声明并将它们声明为{ {1}}。

src1.c

static

src2.c

static int func(int a, int b)
{
    return a+b;
}

通过执行此操作,这些功能中的每一个仅在其定义的模块中可见。

编辑:

如果你想要两个或多个函数来实现一个接口,你需要给它们不同的名称,但你可以使用一个函数指针来选择你想要的那个。

COMMON.H

static int func(int a, int b)
{
    return a*b;
}

src1.c

typedef int (*ftype)(int, int);
int func_add(int a, int b);
int func_mult(int a, int b);

src2.c

#include "common.h"

int func_add(int a, int b)
{
    return a+b;
}

然后你可以选择其中一个:

#include "common.h"

int func_mult(int a, int b)
{
    return a*b;
}

答案 2 :(得分:0)

如果你用每个src [x] .c编译它,你就可以在.c

的任何函数中使用它。

答案 3 :(得分:0)

您可以决定不将函数实现公开给其他翻译单元。在c中,在实现函数的函数签名之前使用关键字static(参见下面的代码);在C ++中,您还可以使用未命名的命名空间。通过这样做,链接器不会给你一个错误,每个翻译单元将使用它自己的实现:

假设以下两个翻译单元main.canother.c。两者都有int function(a,b)的(私有)实现,因此在调用它们时会产生不同的结果:

extern void someOtherFeature();

static int function (a,b) {
    return a+b;
}

int main(){

    int x = function(1,2);
    printf("main: function(1,2)=%d\n", x);
    someOtherFeature();
}

// another.c:
#include <stdio.h>

static int function (a,b) {
    return a*b;
}

void someOtherFeature() {
    int x = function(1,2);
    printf("someOtherFeature: function(1,2)=%d\n", x);
}

输出:

main: function(1,2)=3
someOtherFeature: function(1,2)=2

但是,如果两个翻译单元都公开了他们的实现(即省略了关键字static,那么链接器将报告错误,如duplicate symbol _function in:...

答案 4 :(得分:0)

如果您希望每个源文件使用本地版本的func,只需将其放在未命名的命名空间中:

例如 src1.C

namespace
{
    int func(int a, int b)
    {
        return a+b;
    }
}

然后每个源文件将使用自己的版本。您不需要在标题中声明它。

请注意,带有全局命名空间定义并在标头中声明的原始代码违反了一个定义规则(同一个名称的两个函数定义必须始终具有相同的定义),调用未定义的行为,无需诊断。