Thursday, August 22, 2013

FeedaMail: Comments for Sutter̢۪s Mill

Comments for Sutter's Mill
feedamail.com Comments for Sutter's Mill

Comment on GotW #7a Solution: Minimizing Compile-Time Dependencies, Part 1 by Christopher

For solution 1, you might want to write

  class widget { // "{" means definition  public:      widget();      // ...  };    widget* p;     // ok: allocs sizeof(ptr) space typed as widget*    widget  w;     // ok: allocs sizeof(widget) space typed as widget                 //     and calls default constructor  

Otherwise, trying to compile this code will complain about the widge w line. (The linker ends up complaining anyway, later on…)

Read More »

Comment on GotW #7a Solution: Minimizing Compile-Time Dependencies, Part 1 by Emmanuel Thivierge

To me to have public member function that return incomplete type is actually a bad style and a bad habit. Because you will have to include the header for the return type anyway. It makes dependencies explicit where it doesn’t need to be and it doesn’t help compile time because you need to include it anyway at the point of use. I find it really frustrating to include a file and to get compile errors because i need to include more file because of incomplete type. Those dependencies have no really good ways to be documented either and it would not be the good solution.

I think the good solution is to just include those header for public member and non members functions. Your collegue will thanks you and it should impact the build time anyway.

Read More »

Comment on GotW #7a Solution: Minimizing Compile-Time Dependencies, Part 1 by bcs

Yes technically you can replace “e.h” with “class E;” but that leads to the rather obnoxious situation where I’ve included “x.h” and then go try to use X::h and have to go track down which header E is defined in and include it as well.

Read More »

Comment on GotW #7b: Minimizing Compile-Time Dependencies, Part 2 by Norbert Riedlin

One additional thought that I have not seen up to now in another post is that private inheritance can be considered as “is implemented in terms of”. That means we could add a B member in the Impl class and remove the private B inheritance. Then we could remove the #include "b.h" and replace it with the proper forward declaration class B;. All that can only be done, if we don’t need access to protected parts of B (only a look at the implementation could tell us). Another reason to have to stick to inheritance would be the need to override a virtual function, but the comment says that B has none.

As I write this I see that we could just let the internal class Impl inherit publicly from B. This way we would also have access to B’s protected members. Impl also would not need the mentioned B member.

But I would also object against ‘pimpl’ing the class. As it is now, the class has valid copy and move constructors and valid copy and move assignment operators. If we change the implementation to a pimpl based one, we would have to provide them manually to keep it externally unchanged. I don’t think this is justified just to be able to remove some header files.

Read More »

Comment on GotW #7b: Minimizing Compile-Time Dependencies, Part 2 by Alf P. Steinbach

@Thibaud:

“1. You can now remove #include [missing] in "x.h" and put it in the implementation file.”

Assuming that you meant #include <list<> it is in the implementation file (unfortunately the line in the header avoided deletion, it’s redundant).

“2. You could also put B in Impl and replace #include “b.h” with a forward declaration. Doing this, B and X's public interface remain unchanged.””

No.

The requirement is “as long as X's base classes and its public interface remain unchanged”. Which means: not only the public interface, for whatever interpretation of “public”, but also the base classes.

Private base classes can with some effort be regarded as part of the effective public interface because (1) they participate in name look-up, and (2) the old C-style cast is explicitly permitted to cast to an inaccessible base class (it’s the only cast that can be used for this with well-defined effect).

I find that interpretation a bit unnatural, but it or a similar practical consideration might be the reason why Herb wants to preserve base classes in addition to the normal public interface.

“3. I think operator= has to be defined?”

Right, I forgot that.

It is however rather difficult to do correctly with the information given, because we don’t know whether the original public interface provided copy constructor, or copy assignment operator, for that depends crucially on the nature of classes C and D.

But somehow I don’t think that Herb meant to withhold the copyability information!

So, just assuming that C and D are fully copyable, and making the new method swap_with protected in order to preserve the public interface unchanged, the copying-supporting header can go like this:

  #pragma once    #include <iosfwd>    // None of A, B, C, or D are templates.  // Only A and C have virtual functions.  #include "a.h"  // class A  #include "b.h"  // class B  class C;        // class C  // Class D is not needed in this header, at all.  class E;        // Class E    #ifndef CPPX_NOEXCEPT  #   define CPPX_NOEXCEPT noexcept