简体   繁体   中英

C++ - Can Class Functions be Declared Outside of Header?

I'm fairly new to C++ and trying to write a class that's purpose is to solve a mathematical problem when the class is instantiated with an input. I've broken those calculations up over a couple of sub-functions and so the header/source code looks something like this:

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
}

This works but I have to list the methods intermediateCalculation1/2 in the header file despite their being purely implementation details. As a result, if I want to change some of the details of how the calculations are performed (eg split things into 3 intermediate calculations rather than 2) I would have to change the header file and re-compile every file that includes mySolver.h which seems to defeat the purpose of separating interface from implementation.

My question is:

1) Is there a simple way to do this without having to include the intermediate functions in the header file?

2) Is there a simple way to do this without having to include the intermediate functions in the header file that still lets me access member variables in the intermediate functions ?

I've come across some references to the pImpl technique that could be a solution, but for my purposes that seems unnecessarily complicated.

EDIT: Regarding why this is in a class at all, I've simplified my example for clarity but in my actual code I have multiple outputs, some of which are intermediate results I only want to access some of the time (ie for error checking), hence my choice of class structure.

1) Is there a simple way to do this without having to include the intermediate functions in the header file?

Yes. In addition to this answer , if you put these into an anonymous (unnamed) namespaces you will really hide those implementation details from any access outside of the translation units. It also helps not to confuse the linker in case of name clashes:

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) Is there a simple way to do this without having to include the intermediate functions in the header file that still lets me access member variables in the intermediate functions?

Not really, these would need to be friend ed to do so, which requires them to appear at the class declaration.

You still have the option as your code example does now and pass them the necessary parameters, or go with the pimpl idiom as you mentioned. Since pimpl only needs a forward declaration, I believe you can do the full declaration and definition in an anonymous namespace as well.

You can do that by just defining the function before you use them in the .cpp file. No need to define them in the header file because there is no need to make them member functions. These are just free functions.

Also, you probably would want to put them in an anonymous namespace so they are only visible to the existing file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM