使用命名空间时如何在标头和.cpp文件之间正确定义C ++类

时间:2019-05-30 17:04:27

标签: c++ c++17 header-files

我正在尝试使用C ++ 17编译器在名为numc的命名空间下编写一系列类。目前,我正在研究根求解器类,由于某种原因,当我在头文件中定义函数时,代码可以正常工作。但是,当我在.cpp文件中定义函数时,代码在编译时失败,错误为clang: error: linker command failed with exit code 1

如果我像定义.hpp文件那样定义.hpp文件,则它可以正常工作。

 // Working main.cpp file
 double upper = 3.0;
 double lower = 0.0;
 double guess = 2.0;
 double right_side = 0.0;
 double result;
 result = numc::RootSolver::bisect(upper, lower, right_side, guess, func1);

double func1(double x)
{
    return pow(x, 6.0) - x - 1.0;
}

// Working numc.hpp file
namespace numc
{
    class RootSolver
    {
    public:
        static double
        bisect(double upper, double lower, double right_side, 
               double guess, const std::function<double(double)>& func,
               double uncertainty = 0.001, int iter = 150);
    private:
        [[noreturn]] static void exit_program(int iter);
    }
// ================================================================
// ================================================================
double
    RootSolver::bisect(double upper, double lower, double right_side, 
                       double guess, const std::function<double(double)>& func
                       double uncertainty, int iter)
    {
        for (int i = 0; i < iter; i++)
        {
            if (func(guess) - right_side <= unc and
                func(guess) - right_side >= -unc) return guess;
            else if (func(guess) - right_side > unc)
            {
                upper = guess;
            }
            else lower = guess;
            guess = lower + (upper - lower) / 2.0;
        }
        RootSolver::exit_program(iter);
    }
// ================================================================
// ================================================================
    [[noreturn]] void
    RootSolver::exit_program(int iter)
    {
        std::string one("Function did not converge within ");
        std::string two(" iterations");
        std::cout << one << iter << two << std::endl;
        exit (EXIT_FAILURE);
    }
}

以上面显示的方式定义时,程序可以正常工作并产生1.3477的结果。但是,您可以看到,我不仅定义了.hpp文件中的函数原型,还定义了函数,这是一种不好的形式。这些功能应在numc.cpp文件中定义。

如果我使用上面显示的工作.hpp文件并将其重写,并将函数定义放在.cpp文件中,则会得到以下代码。

// numc.hpp code
namespace numc
{
    class RootSolver
    {
    public:
        static double
        bisect(double upper, double lower, double right_side, 
               double guess, const std::function<double(double)>& func,
               double uncertainty = 0.001, int iter = 150);
    private:
        [[noreturn]] static void exit_program(int iter);
    }
}

numc.cpp代码

#include "numc.hpp"
double
numc::RootSolver::bisect(double upper, double lower, 
                         double right_side, double guess, 
                         const std::function<double(double)>& func,
                         double unc, int iter)
{
    for (int i = 0; i < iter; i++)
    {
        if (func(guess) - right_side <= unc and
            func(guess) - right_side >= -unc) return guess;
        else if (func(guess) - right_side > unc)
        {
            upper = guess;
        }
        else lower = guess;
        guess = lower + (upper - lower) / 2.0;
    }
    numc::RootSolver::exit_program(iter);
}
// ================================================================
// RootSolver PRIVATE MEMBER-FUNCTIONS

[[noreturn]] void
numc::RootSolver::exit_program(int iter)
{
    std::string one("Function did not converge within ");
    std::string two(" iterations");
    std::cout << one << iter << two << std::endl;
    exit (EXIT_FAILURE);
}

我尝试了几种变体,但是无论如何做,当我将成员函数定义放在.numc.cpp文件中时,代码在编译时均失败,并告诉我存在链接器问题。如果有人能指出我的错误,我将不胜感激。

0 个答案:

没有答案