Putting all methods in class definition - c++

When I use the pimpl idiom, is it a good idea to put all the methods definitions inside the class definition? For example:
// in A.h
class A {
class impl;
boost::scoped_ptr<impl> pimpl;
public:
A();
int foo();
}
// in A.cpp
class A::impl {
// method defined in class
int foo() {
return 42;
}
// as opposed to only declaring the method, and defining elsewhere:
float bar();
};
A::A() : pimpl(new impl) { }
int A::foo() {
return pimpl->foo();
}
As far as I know, the only problems with putting a method definition inside a class definition is that
(1) the implementation is visible in files that include the class definition, and
(2) the compiler may make the method inline.
These are not problems in this case since the class is defined in a private file, and inlining has no effect since the methods are called in only one place.
The advantage of putting the definition inside the class is that you don't have to repeat the method signature.
So, is this OK? Are there any other issues to be aware of?

I think you answered your own question : both solutions are equivalent.
However, I wouldn't be so sure that 'inlining has no effect since the methods are called in only one place' : an additional call could exists when the functions are not inlined. But chances are that the compiler is smart enough to optimize them away from the one-line forwarding calls in the outer class.
In the end, I believe it's just a matter of taste.

Advantages:
all code of the class is localized
Disadvantages:
for larger classes: when scrolling is needed, it becomes more difficult to know to which class the function belongs.
dependencies are more easily solved when functions reside after all class declarations. Otherwise, it might be needed that some class declarations are moved after others and some functions still have to be moved after the class declaration when there are mutual dependency of internal classes.

Usually I don't add methods to the Impl inner class, but I can't see any issue if you define the methods inline. It seems to me much more readable than having seperate declaration and definition.

Whether the compiler inlines the methods depends on the compiler and the passed parameters.
In the case of the pimpl idiom, I don't think it matters whether the methods are defined within the Imp's body or not. I personally like them defined outside, because it is easy to see what is really important (like member variables and list of methods).

Related

In C++, how to write full implementation in header for classes and functions (possibly templated)

I usually declare in header file and implement in cpp file, but now I am doing an assignment, and, apparently for brevity, the instructor doesn't want me to do that, but insists that I write all the code in header files.
So, what is the best way to do that?
For classes, should I declare everything first, and then go to the bottom of the page and start implementing?
class myClass
{
void myMethod();
}
void myClass::myMethod() { //.... }
or should I just implement as I declare
class myClass
{
void myMethod() { //... } ;
}
What about free functions?
And when should I write "inline"?
or should I just implement as I declare
Yes, implement them in class, not out of class. When the (questionable) reasoning of your instructor for putting everything into a header refers to brevity, this is obviously the way to go.
What about free functions?
Same as with member functions, define them on the go.
And when should I write "inline"?
You should add inline to all ordinary free functions. It's unnecessary for function templates or in-class member function definitions. When you can use C++17, consider inline variables, too.

How do these two functions defined in the same class manage to call each other without forward declaration?

For the time I'm learning to code with boost/asio. Many code samples make use of the combination of async_accept and bind. In the server code , i come across some thing like this:
class Tcp_server
{
public:
Tcp_server()
{
}
void start_accept(int a)
{
if(a>0)
{
cout<<a<<endl;
handle_accept(a-1);
}
}
void handle_accept(int a)
{
if(a>0)
{
cout<<a<<endl;
start_accept(a-1);
}
}
};
If i make an instance of Tcp_server and call either handle_accept or start accept, it works. But if I drop the Tcp_server class encapsulation, the compiler would complain "handle_accept is not declared". I'm just wondering if the compiler automatically forward declare all the functions defined in the same class. Can anyone explain why?
Functions defined in the definition of a class have exactly the same semantics as if they are only declared in the class definition and then defined immediately after the class definition. The only difference is that such member functions are implicitly declared inline while a function definition is either not-inline or explicitly inline. That is, from the compiler's point of view the functions are declared and the class is defined before the function definitions are considered.
The reason for defining the function after the class definition is simple: without doing so, the class would be incomplete and look-ups of members would fail which is clearly not desirable for member function definitions. As a side effect, functions can readily refer to each other. Since defining member functions in the class definition is primarily for convenience it would also be somewhat inconvenient to require declaration for member functions used later.

What does the statement class foo; mean

I have been going through the code of a project and have encountered the statement
class foo;
.
.
.
.
foo* f1;
in various places. The class has not been declared in any of the headers included either. Can anybody tell me what that means.
It is a forward declaration. It can be used for classes, structs and functions, and it tells compiler that this is defined elsewhere or later.
For classes, there are (at least) two use cases.
1. Full definition not needed
After forward declaration, compiler does not know size or members of class, only name. That is enough for pointers to the class (and references which are basically syntactic sugar around pointers). But often pointer is enough, and then you can avoid including entire header file in another. This helps compilation speed, by avoiding need to recompile everything when one header changes.
myfuncs.h
class MyClass; // forward declaration
void helpMyClass(MyClass &needy);
// here this would give compiler error about incomplete type:
//void badHelp(MyClass needy); // value needs definition
myfuncs.cpp:
#include "myclass.h" // entire MyClass definition
void helpMyClass(MyClass &needy) {
needy.helpMe(false); // needs full definition
}
Important use case for this is the so called PIMPL idiom, also well covered here at SO under pimpl-idiom tag.
2. Two classes need to refer to each others
class node; // forward declarion
class collection {
node *frist; // pointer enabled by forward declaration
}
class node {
collection *owner; // already defined above so works too
}
In this case forward declaration is required to make this work nicely. Just saying in case you see it in the wild, there's the ugly way of using void pointer and casts, sometimes used when novice programmer does not know how this should be done.
I think you're referring to a forward declaration. It tells the compiler that a class named foo will be defined later. Until then it is an "incomplete type", meaning that pointers and references to the class can be defined. Instances of the class cannot be created until it is fully defined.
Your declaration is incorrect? I'm not sure.. I do know that you can't have "any" space "name".. Perhaps you missed an underscore?
I believe you meant:
class foo any_name();
In that case, it's forward declaring a function called any_name that returns a class instance of foo.
Example:
#include <iostream>
class foo any_name(); //The forward declaration..
class foo //the foo class implementation.
{
public:
foo(){std::cout<<"hey";}
};
class foo any_name() //The implementation of the function..
{
std::cout<<"any_name";
//return {}; //Can be used to return a constructed instance of foo.
};
int main()
{
any_name();
}

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?

Declare a C++ class without defining it in the current translation unit

It is possible to declare a class without defining it (forward declaration) as long as it is defined later on within the translation unit. In the case of functions, one can declare a function without defining it within the translation unit, and the linker will link it to its definition in a different translation unit. Is it possible to do the same with class declarations?
(if this is not possible, is there any use to a forwardly declared class without a definition in the current TL, or is that always an error?)
something like this, except this doesn't compile:
mymain.cpp:
class myclass; // declare without defining
myclass::myclass();
void myclass::barf();
int main() {
myclass *m = new myclass();
m->barf();
return 0;
}
myclass.cpp:
#include <iostream>
class myclass { // define the implementation
public:
myclass();
void barf();
};
myclass::myclass() { } //empty constructor
void myclass::barf() {
std::cout << "barfing\n";
}
It is possible to forward-declare a class, but only pointers and references to forward-declared classes can be used. You can't use an actual object of a forward-declared class because the compiler doesn't know enough about it; in particular it doesn't know how large the object is or what its members are. Trying to forward-declare member functions (as you have done) won't work because the syntax of the forward declaration doesn't allow you to specify whether the functions are virtual or non-virtual (or perhaps inherited from some base class).
It is not often useful to forward-declare a class in a source file, but it can be useful in a header file. In particular it's common to forward-declare a class in a library's public header file and use pointers to that type as opaque handles. The class definition remains private to the library but user code can pass around pointers to objects of that class without ever knowing what the class's implementation looks like. This works particularly well when the pointers are smart pointers.
You can, but only if you use exclusively pointers or references to that class. But you can't use code referring to that class' members (variables or methods). You can only use it to declare pointer variables to that class.
I would suggest you create a myclass.h header file with myclass' full declaration, and include that header in mymain.cpp.
You can only do that through hacks.
The declare before use rule doesn't hold within a class (see here).
Otherwise you can do that by declaring your function as a template function, whose template parameter is of myclass (in your example).
The only non-hack way is to define the class (ie. by including the header file its defined in).