首页 > 解决方案 > 来自外部文件 C++ 的函数调用

问题描述

我正在尝试将外部文件中的函数调用到源文件中。但是,当我这样做时,我收到以下错误:

构建错误 Visual Studio C++

为什么我会收到以下错误?我整天都在努力解决它,但一切都是徒劳的。PS我对语言和编程很陌生。过往经历:Python

源码.cpp

#include <iostream>
#include <string>
#include "func.cpp"
using namespace std;

double pow(double x, int y);

int main()
{
    double x;
    int y;
    double answer;

    cout << "Choose a number: " << endl;
    cin >> x;
    cout << "Raised to the power: " << endl;
    cin >> y;

    answer = pow(x, y);

    cout << "Answer: " << answer << endl;

    return answer;
}

函数cpp

double pow(double x, int y)
{
    double result = 1;
    if (x == 0 && y == 0)
    {
        result = -1;
    }
    else
    {
        if (y == 0)
        {
            result = 1;
        }
        else if (y < 0)
        {
            x = 1.0 / x;
            y *= -1;
        }
        for (int i = 0; i < y; i++)
        {
            result *= x;
        }

    }

    return result;
}

标签: c++functionvisual-c++

解决方案


这里发生了几件事。最直接的是您包含的标题之一是声明powor std::pow。尽管我想把这一切都归咎于using namespace std;,好的 ol' Cpow函数足以使编译器脱轨。编译器会找到两个pow具有足够相似参数的 s,但不知道该使用哪一个。而是命名您的函数mypow或将其放置在您自己的命名空间中。

例如:func.cpp

namespace my
{ 
    double pow(double x, int y)
    {
        // guts of pow are unchanged
    }
}

并在 source.cpp

double pow(double x, int y);

变成

namespace my
{ 
    double pow(double x, int y);
}

并且被称为

answer = my::pow(x, y);

这解决了问题1。

问题 2 是您尚未看到的链接器问题。在您的项目中,func.cpp 将被编译为 func.obj。func.cpp 也包含在 source.cpp 中。包含的函数被有效地粘贴到包含文件中,因此,您现在拥有两个正在编译的 func 中所有内容的副本。pow可以在 func.obj 和 source.obj 中找到。

当链接器试图将 func.obj 和 source.obj 组合成一个可执行文件时,这会成为一个问题。链接器找到两个pows,并且与编译器类似,不知道使用哪个。

标准的经验法则是不包括 cpp 文件。让编译器编译它们,链接器链接它们。创建一个标头,公开 cpp 文件中需要在外部使用的函数,并让用户包含该标头。

这使您的程序看起来像

函数.h

#pragma once
namespace my
{
    double pow(double x, int y);
}

函数cpp

namespace my
{ 
    double pow(double x, int y)
    {
        double result = 1;
        if (x == 0 && y == 0)
        {
            result = -1;
        }
        else
        {
            if (y == 0)
            {
                result = 1;
            }
            else if (y < 0)
            {
                x = 1.0 / x;
                y *= -1;
            }
            for (int i = 0; i < y; i++)
            {
                result *= x;
            }

        }

        return result;
    }
}

源码.cpp

#include <iostream>
#include <string>
#include "func.h"
using namespace std;

int main()
{
    double x;
    int y;
    double answer;

    cout << "Choose a number: " << endl;
    cin >> x;
    cout << "Raised to the power: " << endl;
    cin >> y;

    answer = my::pow(x, y);

    cout << "Answer: " << answer << endl;

    return answer;
}

不相关但很好读:为什么“使用命名空间标准”被认为是不好的做法?


推荐阅读