C ++ - 可以在标题之外声明类函数吗?

时间:2017-09-20 17:01:54

标签: c++ header-files

我对C ++很新,并试图编写一个类,其目的是在用输入实例化类时解决数学问题。我已经在几个子函数中破坏了这些计算,所以标题/源代码看起来像这样:

mySolver.h

#ifndef __mySolver_h__

class mySolver
{
private:
    double mInput, mOutput; //member variables
    double intermediateCalculation1(double input);
    double intermediateCalculation2(double intermediateValue1);
public:
    mySolver(double input);
};

#endif

mySolver.cpp

#include "mySolver.h"

mySolver::mySolver(double input)
{
    mInput = input;

    double intermediateValue1 = intermediateCalculation1(mInput);
    double mOutput = intermediateCalculation2(intermediateValue1);

    cout << "Output is: " << mOutput << endl;
 }
double mySolver::intermediateCalculation1(double input)
{
    //do stuff
}

double mySolver::intermediateCaluclation2(double intermediateValue1)
{
    //do stuff while accessing value of member variable mInput
}

这工作我必须在头文件中列出intermediateCalculation1 / 2方法,尽管它们纯粹是实现细节。因此,如果我想更改计算执行方式的一些细节(例如,将事物分成3个中间计算而不是2个),我将不得不更改头文件并重新编译包含mySolver.h的每个文件。这似乎打破了将接口与实现分离的目的。

我的问题是:

1)是否有一种简单的方法可以在不必在头文件中包含中间函数的情况下执行此操作?

2)有没有一种简单的方法可以做到这一点而不必在头文件中包含中间函数,它仍允许我访问中间函数中的成员变量

我发现了一些可能是解决方案的pImpl technique的引用,但出于我的目的,似乎不必要的复杂。

编辑:关于为什么这是一个类,我为了清晰起见简化了我的例子,但在我的实际代码中我有多个输出,其中一些是中间结果我只想在某些时候访问(即用于错误检查),因此我选择了类结构。

3 个答案:

答案 0 :(得分:4)

  

1)是否有一种简单的方法可以在不必在头文件中包含中间函数的情况下执行此操作?

是。除this answer之外,如果将这些命名空间放入匿名(未命名)名称空间,您将真正隐藏翻译单元之外的任何访问权限。在名称冲突的情况下,它也有助于不混淆链接器:

namespace { // <<<< unnamed namespace
    double intermediateCalculation1(double input) {
        //do stuff
    }

    double intermediateCaluclation2(double intermediateValue1, double input) {
        // the member variable mInput should be passed as parameter
    }
}

mySolver::mySolver(double input) {
    mInput = input;

    double intermediateValue1 = intermediateCalculation1(mInput);
    mOutput = intermediateCalculation2(intermediateValue1,mInput);

    cout << "Output is: " << mOutput << endl;
}
  

2)有没有一种简单的方法可以做到这一点而不必在头文件中包含中间函数,这仍然允许我访问中间函数中的成员变量?

不是真的,这些都需要friend来执行此操作,这需要它们出现在类声明中。

您仍然可以选择代码示例现在执行的操作,并将必要的参数传递给他们,或者按照您提到的 pimpl 习惯用法进行操作。由于 pimpl 只需要一个前向声明,我相信你也可以在匿名命名空间中进行完整的声明和定义。

答案 1 :(得分:1)

您只需在.cpp文件中使用它们之前定义该函数即可。无需在头文件中定义它们,因为不需要将它们作为成员函数。这些只是免费功能。

此外,您可能希望将它们放在匿名命名空间中,以便它们仅对现有文件可见。

答案 2 :(得分:-1)

您在cpp文件中定义了两个中间函数,这些函数会在私有作用域内声明这些函数时产生错误。因此,不要在其他文件中定义,只需在类本身内部定义。