Defining non-template methods for a class with template methods - c++

What I am trying to do:
// in foo.hpp
class foo {
private:
int m_a;
long m_b;
public:
foo(); // default constructor (defined in foo.cpp)
template<class T>
int Func1(int a, int b) {
// Func1 definition
// uses member variables m_a, m_b
}
}
// in foo.cpp
#include "foo.hpp"
foo::foo() {
// Foo constructor
// Uses member variables m_a, m_b
}
I understand templates in C++ work as a pattern and are instantiated on demand. Therefore, for the compiler to understand whats happening, the template method definition needs to be in the header file (or else I need to use the other workarounds like using an implementation file (.tpp) and including it in foo.hpp)
This also applies to a template class with non-template methods. The non-template methods need to be defined in the header file.
My question is Foo is a regular class and has one template method and a regular constructor. Should the constructor be defined in the header file or can it be defined in a separate source file?
I ran into this issue at work. Moving the constructor definition to the header file seems to fix the issue.
It would be helpful if someone could provide an explanation for this behavior.

Should the constructor be defined in the header file or can it be defined in a separate source file?
As long as the constructor and the class itself is not a template, you can define it wherever you would like.
One point I would like to clarify: A templates definition simply needs to be visible at the point of instantiation. This does not actually mean that a template must always be defined in a header; it can just as easily be defined in the source file, if its only uses are meant to be internalized within the source file (e.g. it's a private function, only used internally).
Often this does mean that it should be in a header for cases where it's either a public function template, or a class template -- but there are exceptions to this rule.

Related

extern template & incomplete types

Recently when I was trying to optimize my include hierarchy I stumbled upon the file a.hpp:
template<class T>
class A
{
using t = typename T::a_t;
};
class B;
extern template class A<B>;
which seems to be ill-formed. In fact it seems as if the extern template statement at the end causes an instantiation of A<B> which causes the compiler to complain about an incomplete type.
My goal would have been to define A<B> in a.cpp:
#include <b.hpp>
template class A<B>;
This way I avoid having to include b.hpp from a.hpp which seems like a good idea to reduce compile time. However it does not work (a.hpp on itself doesn't compile!) Is there a better way of doing this?
Note: Of course I could just not use explicit template instantiation but this is not what I want! I would like to "precompile" A<B> to save compilation time if it were used, but if A<B> is not used I don't want to include b.hpp in every file that uses a.hpp!
The extern template declaration prevents the instantiation of member function bodies, but it forces the instantiation of the class definition, since the compiler needs that anyway, and the class body needs a full definition of the template argument since it accesses its members. I'm afraid that hiding B's body from users of A<B> is not possible.
extern template is an optimization, but it doesn't change the fundamental workings of the instantiation mechanism.
From http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1448.pdf
The extern specifier used to declare an explicit instantiation of a
class template only suppresses explicit instantiations of definitions
of member functions and static data members not previously specialized
in the translation unit containing the declaration.
Thus, if a definition of B is required in A, you cannot use an extern template without knowledge of B. You could of course try to get rid of that requirement. In the given case, you could remove the using t declaration and have a meta function to yield that type:
template<typename T>
struct get_a_t;
template<typename T>
struct get_a_t<A<T>>
{
using type = typename T::a_t;
};
Not sure it that is feasible in your case. As soon as A needs to store a B or a B::a_t, you need B. References and pointers would be OK, though.
The final extern template class A is telling the compiler that there is in some compilation unit a declaration of such template specialization. The compiler goes on and then the linker should complain about not finding the correct class. It is not ill formed; it depends on the use case. You can define in a separate cpp file the template A. This will obviously just reduce a bit the compile time if you compile it over and over. You can do different structures:
one a.hpp with just the class A template.
one b.cpp file with the class B along with its .h file. (is it a template?)
b.cpp includes a.hpp and inside you make an explicite template instantiation template class A; (not with extern).
At this point whenever you need to use that template you can just write
extern template class A;
in your file and link the compiled b.cpp file. If you include the a.hpp file since you still need the template you won't recompile it since you have the extern command.

What is a member function in c++?, does it contain a body?, is it defined in the .h or .cpp file? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I'm new in c++.
I'm required to define member functions. I am more familiar with java. I actually confused by the term "member function".
Do we have to define it in the header .h file or the .cpp file?
I am confused by the term of member function
Everything that belongs to a class or a struct is called a member of that class. Hence, we can have member functions. Below is a little exmaple:
class MyClass
{
public:
MyClass();
void myFunction();
int number;
}
Here you have myFucntion() and number members of MyClass
Do we have to define it in the header .h file or the .cpp file?
In C++, it doesn't matter where you define or declare a function or a class.
But keep in mind that putting declaring classes in .h files is better. It will lead to faster compilations of your project. So you should have something like:
// myClass.h
class MyClass
{
public:
MyClass();
void myFunction();
int number;
}
// myClass.cpp
myClass::myClass()
{
// this is a constructor
number = 10;
}
void myClass::myFunction()
{
// this is my function
cout << number;
}
Every function in C++ is a member
Member of a namespace. These are sometimes called "global functions", although that termis not completely correct. They consist of all functions in the global namespace and any functions in user defined namespaces, hence they are called namespace-scope functions.
Member of a class. These are called member functions (even though they are not the only functions that are members!). They can be further separated by non-static member functions and static member functions (I take it you know the difference of this from Java).
Alternate syntax:
class MyClass{
public:
void MyFunction(void); // prototype
}
MyClass::MyFunction(void){ // actual function
// code goes here
}
Think of member function as a method.
In Java, your method (member function) within a class might look something like:
public class MyClass {
public void MyMethod() {
// do stuff
}
}
This is very much the same in C++:
class MyClass
{
public:
void MyMethod();
}
As far as how I've been taught, you declare your class and its members in a header file (.h) and then define them in a .cpp file. You don't have to do it that way and can keep everything with your .cpp file. It's just a better practice to separate them.
in C++ does not matter ...
member functions are just functions inside class (or struct)
you can have headers
you can also have body only ...
if you separate headers and bodies into *.h(pp) and *.cpp files
then you can cross referencing more classes to each other
here some examples:
class C1
{
public:
int a,b,c; // some variables
void f0(); // header only
void f1() { c=a+b; }; // inline body only
friend void f2(); // not a member but can have access to class private things
friend void f3(C1 &x); // not a member but can have access to class private things
};
void C1::f0() { c=a+b; } // body(C1 member) ... can be in separate file
void f2() { C1 c1; c1.c=c1.a+c1.b; } // just function not a member
void f3(C1 &x) { x.c=x.a+x.b; } // just function not a member
if your not member function are accesing only public parts of class then they do not need to be friend.
also there are some restrictions for inline bodies on some compilers
like you can not use asm {} for example...
First, your question "Do we have to define it in the header .h file or the .cpp file?"
You can define (write code for) member functions in either, with different implications.
Any function defined in a header file needs to be an inline function (because it will be included to many .cpp files, and being inline means, this is ok). Luckily, if you combine declaration and definition and do it inside class {...}, they are automatically considered inline, so it "just works".
If you define the member function in a .cpp file, then you need to have the declaration inside class {...}. And if you want to use the class from many .cpp files, then it should go to a .h file, but it can also be earlier in the same .cpp file.
More explanation:
Member function is same as method. Also, for the purposes of this answer, function overloads (same name but different arguments, return value is not considered) are different functions.
In C++ there is separate declaration and definition, though they can be rolled into one. Any function is declared by having just ; instead of function body { /* ...code... */ }. If this declaration is inside a class {...} or struct {...}, then it's a member function. A function call is ok in code as long as there's declaration before the call. Then later on linker will complain if there's no actual function definition, that is a block of code to call. There can be any number of declarations for a function, but only one definition (except for inline functions, where compiler and linker assume duplicate definitions are all the same, so they better be or funny things can happen).
About .h and .cpp files: C++ (and C), .h files are eseentially copy-pasted to the .cpp file during compilation. You could remove the #include and copy paste the contents, and it would be exactly same thing for compiler. But from practical standpoint, definitions go to a .h file, and then they are included in may .cpp files, and because they are declarations, it's ok to have them as many times as you like. But actual definitions go to .cpp files, so they get compiled exactly once, so linker is happy.
Finally a bit about inline functions. If you have a member function definition inside class {...}, it is automatically considered to be inline. You include the same .h file with these inline definitions to many .cpp files, but it is ok because they are by default marked inline (and also, since the code is in same .h file, all definitions should be the same, unless you use some #ifdef preprocessor stuff wrong).
Example:
myclass.h
class MyClass {
void memberFunc1() {
// here is function declaration and definition combined,
// by default inline, so can be include to many .cpp
}
void memberFunc2(); // here's just declaration
}
myclass.cpp
MyClass::memberFunc2() {
// defintion of member function, not inline, must exist exactly once
}

Why can I declare constructor out of the class

Consider this link. See this code:
class MyClass
{
public:
MyClass();
~MyClass();
private:
int _a;
};
MyClass::MyClass()
{
}
MyClass::~MyClass()
{
}
We can declare constructor out of the class.
Why can I declare constructor out of the class and why we should do this?
You cannot declare constructor out of the class. You are talking about constructor definition.
class MyClass
{
public:
MyClass(); // declaration
};
MyClass::MyClass() // definition
{
}
You should read this.
The main reason why you should define your constructor outside the class is for readability. It is clearer to declare your class in the Header file and define it in the source file. You can apply this rule any members of your class.
A little quote from the standard :
12.1 Constructors
struct S {
S(); // declares the constructor
};
S::S() { } // defines the constructor
You cannot. This is the constructor declaration, which has to be in the class definition:
// MyClass definition, possibly in .h file
class MyClass
{
public:
MyClass(); // default constructor declaration
...
};
and this is the constructor's definition
// MyClass default constructor definition, possibly in .cpp file
MyClass::MyClass() { }
What you are referring to is the constructor's definition. You can define it outside of the class definition to allow you to de-couple one from the other. Usually this means you put the class definition in a header file, to be included by client code, and the constructor definition (as well as other class member function definitions) in an implementation file that gets compiled. This way, users of your code have no compile time dependency on said definitions.
The main reason for defining the constructor (or any member function) outside of the class declaration is so that you can have a header file and an implementation file. This makes your code clearer to read and allows you to distrbute the interface to your class (the header file) without providing the implementation details.
You can not declare a constructor or anything part of the class, outside it, but you can define
It's a common c++ programming practise of using 2 files for 1 class
For example,
ClassG.h
class ClassG
{
public:
ClassG();
~ClassG();
void anyfunc(int anyarg);
private:
int anydata;
};
ClassG.cpp
#include"ClassG.h"
ClassG::ClassG()
{
//something
}
ClassG::~ClassG()
{
//something
}
void ClassG::anyfunc(int anyarg)
{
//something
}
General Syntax
While declaring, inside .h file type returntype methodname(args_if_any);
While defining in a .cpp file type returntype ClassName::methodname(args_if_any){}
First of all, you have your terminology confused, you need to read What is the difference between a definition and a declaration?. You can not declare a constructor outside of a class but you can define it outside of a class.
So on to the questions as you meant them:
Why can I define a constructor out of the class
Basically the standard has this to say about member functions in section 9.3.2:
A member function may be defined (8.4) in its class definition, in which case it is an inline member function (7.1.2), or it may be defined outside of its class definition if it has already been declared but not defined in its class definition.
So the standard says this is ok, next question:
why we should do this?
It makes your code cleaner and easier to digest, you can separate your declarations into header files and your implementation into source files. This previous thread Why have header files and .cpp files in C++? goes into this topic in more detail.
Yes, you can define the constructor inside the class no matter that whether you are
using .h file or .cpp file. Actually the main difference between both the file is,
header file never compile it only use for checking syntax during compilation of .cpp
file.
Method that you define inside the class by default inline function. If you define one
constructor inside the class it's fine but, if you required to define more than one
constructor then 2 problem occur
Problem 1:
As we know that, when you call inline function it will paste code in called
function that increase the code size and required more memory.
Problem 2:
Reduce the readability of code.

Resolving Inclusion Ordering

I am working on a codebase that is not my own, that has the following layout:
object.h:
// Objects are defined
// #include "tickets.h" (functions to access the objects)
// An access-handler object is defined
I want to introduce a class that knows about the objects, can be accessed from functions in tickets.h, but can also use the access-handler object. The functions are separate, i.e. class functions that are called in tickets.h do not use the access-handler (I wouldn't know where to start if that weren't the case).
Therefore my class needs to be defined before tickets.h, but some of its functions need to be defined after the access-handler. Is there a way to do this without splitting it up into two header files something like the following:
// Objects are defined
// -- include declaration of class, and definition of functions that tickets.h needs
// #include "tickets.h"
// An access-handler object is defined
// -- include functions of class that need the access-handler
This seems very messy splitting things up like this into two separate files, I was hoping to keep everything contained.
Thanks for any help, I clearly only have a very rudimentary understanding of declarations/definitions in c++.
EDIT: If I use forward declaration and include it before tickets.h (with the class declared in mynewclass.h and functions defined in mynewclass.cc) will mynewclass.cc be able to use objects declared after the inclusion of mynewclass.h? Namely the access-handler object.
EDIT2: Something like this:
object.h:
class obj { // definition }
#include "tickets.h"
class obj_handler {
public void handle { // code }
}
tickets.h:
void do_something(obj o){
communicator.foo();
}
My object (communicator):
class communicator {
public:
void foo() { // code }
void bar() { // use handle() from obj_handler }
}
As you can see, my communicator needs to be used in tickets.h, but can't be defined until after obj_handler. So where should I include it?
If I correctly understand your question - you can use forward declaration to solve this problem. This will allow you to declare some class before defining it's methods. For example:
// this is forward declaration of class A, no definition provided
class A;
class B
{
// uses A
A * a_;
};
// class A definition
class A
{
// may use class B now
B * b_;
};
I'm not quite sure whether I understand this right and don't have enough reputation here yet to make this a comment, so let me try to answer your question this way, please feel free to follow up if I'm guessing wrong:
I believe what you are referring to is an entire class definition, i.e., one including all function definitions within the class declaration. Other than that, it is not very common to see object definitions followed by preprocessor directives. What is typical though is a forward declaration of functions and a class prototype.
So, for example, you could declare in some header.h:
class C
{
public:
void method1(void);
int method2(void);
};
And in some implementation.cpp the definition of the functions like:
void C::method1(void) { /*...*/ }
In the other file preceded in the inclusion chain by your access-handler you then define the other function:
int C::method2(void) { /*...*/ }
What do you mean by access-handler, by the way?
Oh, and your linker likely will yell somewhat at you if you do function definition in a header file.
With regard to your addenda: everywhere you put a forward declaration, loosely speaking, the compiler will insert a copy of the declaration in question, consider it a soft link in the context of file systems. There are negative implications associated with it, like increased duration and the memory load of compilation if you have many forward declarations of the function signature or class. It's impossible to tell whether this will word in your particular situation since only you know the actual code in question. But most likely it would work.
Take a look at these pages:
http://en.wikipedia.org/wiki/Forward_declaration
When can I use a forward declaration?

How to specialize a non-inline templated member function ? (for use in different translation units)

Context
We develop a templated settings system class, that will be part of an API we expose to users of different architectures (fewer words : we should not rely on compiler-specific behaviors)
The generalized code would look like :
In the header
namespace Firm
{
// Class definition
class A
{
template<class T>
void foo(T* aParam);
};
// Non specialized template definition
template<class T>
void A::foo(T* aParam)
{
//...
}
// Declaration of a specialization
template<>
void A::foo<int>(int* aParam);
} // namespace
In the CPP file
namespace Firm
{
// Definition of the specialized member function
template<>
void A::foo<int>(int* aParam)
{
//...
}
} // namespace
Questions
Everything runs fine with gcc 4.x. (i.e. Different compilation units use the specialized methods when appropriate.) But I feel uncomfortable since I read the following entry :
Visibility of template specialization of C++ function
Accepted answer states, if I correctly understand it, that it is an error if the definition of the specialization of a template method is not visible from call site. (Which is the case in all compilation units that are not the CPP file listed above but include the header)
I cannot understand why a declaration would not be enough at this point (declaration provided by the header) ?
If it really is an error, is there a correct way to define the specialization for it to be :
non-inline
usable in any compilation unit that includes the header (and links with the corresponding .obj) ?
Put the declaration in the header file.
The compiler either needs to instantiate the template (needs the definition) or you need to use c++0x extern templates
look here:https://stackoverflow.com/a/8131212/258418
edit
# Single definition rule:
YOu should be fine since I expirienced the following behaviour for templates:
Create them in the different o files (multiple time, time consuming due to several compilations), when the linker comes in it removes the duplicates and uses one instantiation.
also look at this answer/wiki link: https://stackoverflow.com/a/8133000/258418
edit2
for classes it works like this:
extern template class yourTemplate<int>; //tell the compiler to just use this like a funciton stub and do no instantiation. put this in the header
template class yourTemplate<int>; //instantiation, put this in a c file/object that you link with the project
for your function it should work like this:
// Declaration of a specialization in your header
extern template<>
void A::foo(int* aParam);
//in your cpp file
template<>
void A::foo<int>(int* aParam) {
code...
}
template class A::foo<int>(int* aParam);