Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Namespace or Class, which is better for encapsulation of only function members

So, let's say I have a few functions to deal with opening/closing of files.

Is it better to make a class with all these function declared statically or simply put the "public" function in the header file of namespace "file", and put the rest "implementation details" in the .cc file?

Below are the code samples.

It's a bit long for the namespace one, as I want to make it as clear as possible.

THANKS!!


the class implementation

Header:

#ifndef FILE_H
#define FILE_H

#include <iostream>
#include <fstream>

include "common.h"

enum Errorcode {
    FILE_CANNOT_OPEN,
    FILE_CANNOT_CLOSE
};

class file {

public:
    static common::Lines toLines(std::string filename);

private:
    static void err(Errorcode e, std::string msg);
    static void toLines(std::ifstream &ifs, common::Lines &lines);

};

#endif

.cc file:

/*just the implementation details of above class.*/

the namespace implementation

Header:

#ifndef FILE_H
#define FILE_H

#include <iostream>
#include <fstream>

#include "common.h"

namespace file {

common::Lines toLines(std::string filename);

}

#endif    

.cc file:

namespace file {

enum Errorcode {
    FILE_CANNOT_OPEN,
    FILE_CANNOT_CLOSE
};

void err(Errorcode e, std::string msg);
void toLines(std::ifstream& ifs, common::Lines &lines);

common::Lines toLines(std::string filename)
{
    std::vector<std::string> lines;

    try {
        std::ifstream ifs(filename.c_str());
        if (ifs.fail()) throw FILE_CANNOT_OPEN;

        toLines(ifs, lines);

        ifs.close();
        if (ifs.fail()) throw FILE_CANNOT_CLOSE;
    }
    catch (Errorcode e) {
        err(e, filename);
    }

    return lines;
}

void err(Errorcode e, std::string msg)
{
    switch (e) {
        default:
            std::cerr << "Unknown error.\n";
            break;
        case FILE_CANNOT_OPEN:          
            std::cerr << "file \"" << msg   
                << "\" could not be opened.\n"; 
            break;
        case FILE_CANNOT_CLOSE:         
            std::cerr << "file \"" << msg   
                << "\" could not be closed.\n"; 
            break;
    }
    std::exit(-1);
}

void toLines(std::ifstream& ifs, common::Lines &lines)
{
    std::string line;

    while(std::getline(ifs, line)) {
        lines.push_back(line);
    }

    ifs.clear();    // clear error bit set by getline()
}

}                    
like image 953
Jimmy Lu Avatar asked Jan 30 '12 05:01

Jimmy Lu


Video Answer


2 Answers

Superficially, static class functions and namespaced functions are almost identical, and indeed classes were used in the early days before namespace support became widespread.

Nowadays, you should do what most expresses the logical structure (i.e. the mental model) of your program. If you are grouping related functions, it's a namespace.

However, the technical differences in a nutshell is that namespaces participate in argument-dependent lookup (ADL), while class member functions don't, but classes can be turned into templates and specialized. If any of those semantic differences is important to you, then that consideration may help you make the right choice.

like image 144
Kerrek SB Avatar answered Oct 13 '22 04:10

Kerrek SB


There's a simple question that covers most situations: If you made it a class, would an instance of that class make sense and accomplish something useful?

If an instance is useful, then you want a class. Otherwise, a namespace is probably a better choice.

like image 44
Jerry Coffin Avatar answered Oct 13 '22 02:10

Jerry Coffin