Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ what's the best way to make some functions inside source file private?

// myclass.h
#pragma once
void publicFunction();

//------
// myclass.cpp
#include "myclass.h"
#include <iostream>

void privateFunction() {
    std::cout << "Hello world\n";
}

void publicFunction() {
    privateFunction();
}

//-------
// main.cpp
#include "myclass.h"
#include <iostream>

void privateFunction() {
    std::cout << "Hello main\n";
}

int main()
{
    privateFunction();
}

The above program will fail to compile (privateFunction(void) already defined in myclass.obj). One way to solve this problem is by defining a namespace inside the source file:

#include "myclass.h"
#include <iostream>

namespace MyClass
{
    void privateFunction();
    // add a bunch other private functions here
}

void MyClass::privateFunction() {
    std::cout << "Hello world\n";
}
//---
using namespace MyClass;

void publicFunction() {
    privateFunction();
}

Is this the correct way to solve this problem? I feel like this might cause some problems later, but I don't know what is the correct way.

like image 616
Duke Le Avatar asked Dec 31 '22 22:12

Duke Le


2 Answers

If you declare a function in a header file, it's not that private to begin with. If privateFunction is supposed to be an implementation detail, consider declaring it only in the translation unit. To this end, you have two common options.

  1. Use an anonymous namespace in the implementation file.

    namespace {
      void privateFunction() {
        std::cout << "Hello world\n";
      }
    }
    

    This way, you can call privateFunction() from publicFunction, still guarding any usage of privateFunction from outside of the compilation unit.

  2. Make the function static within the translation unit.

    static void privateFunction() {
        std::cout << "Hello world\n";
    }
    

    which has the same effect as 1.

Choosing among 1. and 2. is mostly a matter of taste. If you like to order function definitions such that called functions appear below the calling ones, go with 2., as 1. enforces function definitions at the point of their declarations.

Note that a drawback of such isolation is a reduced ability to write specific unit tests for the helper functions, as you cannot link against those from "outside".

like image 122
lubgr Avatar answered Jan 13 '23 11:01

lubgr


Solution 1:

Declare the function static.

static void privateFunction() { ... }

Solution 2:

Declare the function inside an unnamed namespace.

namespace {
    void privateFunction() { ... }
}

In both cases the function gets internal linkage, meaning it's visible only within the translation unit.

like image 30
rustyx Avatar answered Jan 13 '23 12:01

rustyx