000golabi's blog

By 000golabi, 10 years ago, In English

I don't want to write a .cpp file for every simple c++ class.

when I write a class definition and declaration in a single .hpp file, the linker complains about multiple definition of member functions which are not implemented inside the body of the class or defined with inline keyboard.

For example this will work but member functions will become inline :

// log.hpp file
#pragma once
#include<iostream>

class log {
  private:
    static int m_cnt = 0;
  public:
    void log();
};

inline void log::log() {
    std::cout << ++m_cnt << std::endl;
}

So I use templates to get rid of linker complaints and hope that member functions will not become inline(do they ?):

// log.hpp file
#pragma once
#include<iostream>

template<typename T>
class log_t {
  private:
    static int m_cnt = 0;
  public:
    void log();
};

template<typename T>
void log_t<T>::log() {
    std::cout << ++m_cnt << std::endl;
}

// some random type (int)
typedef log_t<int> log;

And then I can simply use log class in multiple .cpp files without linker complaints.

even when i use this method will member functions become inline ?

  • Vote: I like it
  • 0
  • Vote: I do not like it

»
10 years ago, # |
  Vote: I like it +9 Vote: I do not like it

You could use namespaces to prevent this multiple definition error while linking. Unnamed namespaces: http://stackoverflow.com/a/357427

»
10 years ago, # |
  Vote: I like it +1 Vote: I do not like it

Anonymous namespaces, as ximo answered, are the way to solve this problem. The other two are inlining (and that's what is automatically done when you define a function inside a class) and templates, as you've already tried.

By the way, why do you need this? What's wrong with adding inline specifier or defining functions inside the class (which is the same)? Are you trying to decrease executable's size or something?

Another option is static functions, but they are deprecated since anonymous namespace is a similar, but more powerful tool.