3

我正在用 Visual C++ 2010 编写函数重载程序。以下是我的代码

// overload.cpp : Defines the entry point for the console application.

#include<Windows.h>
#include<iostream>
#include<conio.h>

using namespace std;

//abs is overloaded in 3 types
int abs(int i);
double abs(double d);
long abs(long  f);

void main()
{
    cout<<abs(-10)<<"\n";
    cout<<abs(-11.0)<<"\n";
    cout<<abs(-9L)<<"\n";
    getch();
}
int abs(int i)
{
    cout<<"using integer abs()\n";
    return i>0? -i:i;
}
double abs(double d)
{
    cout<<"using double abs()\n";
    return d>0? -d:d;
}
long abs (long l)
{
    cout<<"using long abs()\n";
    return l>0?-l:l;
}

我在双腹肌和长腹肌功能方面遇到问题

1>c:\users\abc\documents\visual studio 2010\projects\overload\overload\overload.cpp(22): error C2084: function 'double abs(double)' already has a body
1>c:\users\abc\documents\visual studio 2010\projects\overload\overload\overload.cpp(26): error C2084: function 'long abs(long)' already has a body

为什么会出现这个问题?我已将编译从 c 更改为 c++ ,但最近我运行了另一个用于重载的程序,它起作用了。我不知道怎么做?这是代码。

#include<iostream>
#include<cstdio>
#include<conio.h>
#include<cstring>
using namespace std;
void stradd(char*s1,char*s2);
void stradd(char*s1,int i);
void main()
{
    char str[80];
    strcpy(str,"hello");
    stradd(str,"there");
    cout<<str<<"\n";
    getch();
}
//concatenate a string with a "stringized "integer
void stradd(char*s1,int i)
{
    char temp[80];
    sprintf(temp,"%d",i);
    strcat(s1,temp);
}
//concatenate 2 strings
void stradd(char*s1,char *s2)
{
    strcat(s1,s2);
}

输出是 hellothere

4

4 回答 4

5

您的问题来自abs为某些类型(例如double. 您不允许函数具有完全相同的标头(即,相同的返回类型、相同的名称、相同的参数列表、相同的限定符,例如const)。

有两种方法可以避免这种情况:

  1. 使用标准库:std::abs很好,不需要自己实现
  2. 命名方法absoluteValuemyAbs任何您喜欢的名称,但不是abs

第三种方法,即using namespace std根据您的评论删除不起作用。这是因为您包括Windows.h. 这本身包括一堆标题,可能包括math.h. abs这给出了一个在全局命名空间中调用的方法。如果需要,最好不要包含Windows.h和包含。cmath然后,abs仅在 namespace 中声明std,因此您可以使用它来调用它,std::abs并且不同于abs.

于 2013-07-18T10:41:26.460 回答
4

当重载决议不能选择一个函数作为唯一的最佳匹配时,调用是不明确的。模棱两可的调用会产生编译错误。

std已经有一个带有abs()以下签名的:

int abs (int n);

因此,当您尝试重载它时doublelong它会导致编译器产生歧义。

如果您是学习编码的初学者,我建议您使用库中未定义的函数名称(至少是您包含的函数名称)。

stefan 已经给出了解决方案:

使用命名空间标准删除;并明确写std::cout

或者

将您的函数重命名为 absoluteValue 或其他名称

或者

在函数声明和调用中使用显式命名空间。(未经测试,虽然它应该工作)

把你的函数放在一个classornamespace中。

也许会为您提供一些见解(来自 SO)。

编辑:

第二个问题的重载函数 stradd() 未在任何其他库中定义。这就是为什么没有编译错误。代码中的以下函数签名将导致错误:char * strcat ( char * destination, const char * source )

于 2013-07-18T10:39:16.493 回答
2

您的主要问题是您使用全局命名空间。只需在您自己的命名空间中声明您的函数,所有名称冲突都将消失。
让我解释一下为什么会出现这些编译时错误。
在您包含的标题中的某处有double abs(double)long abs(long)功能。然后,您将自己创建具有相同签名的函数。所以编译器只是不知道当你调用其中一个时要使用什么——有两对相等的函数。所以它拒绝编译它,你会得到这些错误。
所以你有 2 个选择 - 希望每次你想要创建一个函数时,你都会选择一个唯一的名称,或者只是创建一个命名空间,并且你的函数名称应该只对命名空间中的另一个函数是唯一的。
而且它'void func(int i)重载void func(float f),但void func(int i)覆盖void func(int i)。您可以覆盖子类中的超类成员函数,但不能覆盖独立函数,例如abs().

于 2013-07-18T10:55:32.067 回答
0

只需用另一个更改 abs 函数名称。abs() 是一个关键字,因此它显示错误。

于 2022-02-03T19:04:02.967 回答