| ||||
| 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 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 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
“1. You can now remove #include [missing] in "x.h" and put it in the implementation file.” Assuming that you meant “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 But somehow I don’t think that Herb meant to withhold the copyability information! So, just assuming that #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
Subscribe to:
Comments (Atom)
|