Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where should I implement my class method?

Tags:

c++

I aware of three different kind of implementation "locations" for my class methods:

1) Define the method inside my class (.h file) and implement it in my .cpp file

//.h
class Foo
{
  int getVal() const;
};


//.cpp
int Foo::getVal() const
{ return 0; }

2) Define and implement the method inside my class (.h file).

//.h
class Foo
{
  int getVal() const
  { return 0; }
};

3) Define the method inside my class and implement it outside the class but inside my header file.

//.h
class Foo
{
  int getVal() const;
};

int Foo::getVal() const
{ return 0; }

What are the main differences between these three approaches?

like image 972
Nick Avatar asked Feb 02 '15 17:02

Nick


People also ask

How do you implement a class method?

A class method is a method which is bound to the class and not the object of the class. They have the access to the state of the class as it takes a class parameter that points to the class and not the object instance. It can modify a class state that would apply across all the instances of the class.

When should I use class methods Python?

Class methods are used when we are dealing with factory methods. Factory methods are those methods that return a class object for different use cases. Thus, factory methods create concrete implementations of a common interface. The class method can be called using ClassName.

Why do we use class method?

Class methods are typically useful when we need to access the class itself — for example, when we want to create a factory method, that is a method that creates instances of the class. In other words, classmethods can serve as alternative constructors.

Why do we create class method in Python?

Classes provide a means of bundling data and functionality together. Creating a new class creates a new type of object, allowing new instances of that type to be made. Each class instance can have attributes attached to it for maintaining its state.


3 Answers

There are three elements to this question: readability (how good the code looks), compilation (how much the compiler can optimize it) and implementation hiding (If you use the code as a library, you may not want to explicitly share your special sauce with the world).

Method one exposes only the interface for the function in the header file. This means you show a nice clean interface, and your implementation is not exposed in plaintext. However, the code cannot be inlined across compilation units, so it has the potential to be a little slower in runtime (in practice, this only matters for a very, very very small percentage of the code). THIS SHOULD BE YOUR DEFAULT WAY TO GO.

Method 2 is implicit inlining. Long functions will clutter up your class which (imho) is bad. Also exposes your implementation to the world. However, the function can be inlined and is less verbose than defining it in another place. I reserve this for very small functions.

Method 3 is actually illegal, as you will break the one-definition rule, but the following is fine:

//Foo.h
class Foo {
  int getVal() const;
};

inline int Foo::getVal() const { 
  return 0; 
}

I use this when I want to keep the class definition clean but want the function definition in the header file (for inlinable or template functions).

like image 142
IdeaHat Avatar answered Nov 02 '22 10:11

IdeaHat


(1) will compile faster for a large project (only have to compile the definition of getVal once in Foo.cpp, and only have to recompile one thing if definition changes), and you get a very clear interface for a class for people who want to look it up. On the other hand, you can't inline getVal().

(2) and (3) will compile slower and add way more dependencies to your definitions changing. But you can inline getVal(). Also this is required if getVal is a template function. NOTE (3) will cause linker errors if your header is included multiple times - you'll have to mark remember to label your function inline. This is a good reason to prefer (1) and (2) to (3).

Really it's not a matter of picking (1) vs (2). You will probably use both in large projects - put the definitions of the functions that should be inlined (and templates) in the header, and put the ones that inlining makes less sense for in the cpp.

like image 34
Barry Avatar answered Nov 02 '22 10:11

Barry


A minor note before I begin, there are lots of words that are very similar used to describe these things, I will be using declaration for the portion in the header file (int getVal() const) and implementation for the portion in the cpp file (int Foo::getVal() const). Apologies if these aren't perfectly accurate.

Also note that benefits are penalties for the others, in case that isn't clear.

1) Define the method inside my class (.h file) and implement it in my .cpp file

This is considered the standard method, and generally accepted to be the default (there are numerous exceptions, so default might be a little strong).

It separates the declaration from the implementation. This provides a few benefits:

  • You only need to compile the implementation once. This could potentially save compilation time.
  • You only need the declaration to reference. This can avoid ordering issues and is vital for circular references between classes.
  • You don't distribute your implementation, this can be good for closed source systems as you often have to distrbute lots of your .h files for others to plug into your system.

2) Define and implement the method inside my class (.h file).

This is called an inline implementation, it should be used in simple implementations only. It has a few benefits too:

  • Most compilers take this as a huge inline hint. It doesn't guarantee inling but it is very likely, which for simple methods can be a win. Property style methods are a common example.
  • Your implementation is trivial to find as it is straight in the declaration.

3) Define the method inside my class and implement it outside the class but inside my header file.

I haven't seen this before, but would assume it is used when the definition is non-trivial but you want the inline benefits of 2. IdeaHat mentions that the inline keyword is required in this case.

like image 1
Guvante Avatar answered Nov 02 '22 08:11

Guvante