Advertisement

Reducing header dependencies

Started by March 12, 2001 04:03 AM
14 comments, last by Wunibald 23 years, 10 months ago
Hi there I posted this a few days ago at ProgrammersHeaven, but didn''t get any answers, so I try it here. e.g. #ifndef SectionsH #define SectionsH class CClass2; //forward-declaration to reduce header- //dependency //#include "Class2.h" Not necessary now class Class1 { void Function1(CClass2* pClass2); } #endif This is how I forward-declare CClass2 to reduce header dependency. But e.g. I want to add a Function2(ETMyEnum Enum); to Class1. ETMyEnum is an enum declared in Class2.h. Now I have to include Class2.h in Class1.h, which gives my header dependency. Is there a way to forward-declare enums and typedefs, too? Or a work-around to this problem? Do I really have to use int-parameters instead of enum? Wunibald
(Computer && !M$ == Fish && !Bike)
Hello.

I tried it out in vc++ 6 now and it seems to
be possible to forward an enum just as you forward a class or
a struct.

enum ETMyEnum;

You don''t even have to use references or pointer to the enum
in the function headers because the compiler knows that an enum always is an int.



------------------------------
- Derwiath -
------------------------------- Derwiath -
Advertisement
Why not put your enum(s) in another header file that you include in both class1.h and class2.h? Of course that might separate stuff that goes together, but you got to weigh that to the gain.
The problem with forwarding an enum is that you won't be able to use the values until you have the whole definition included, but if that's ok, then forwarding will work.

Edited by - amag on March 12, 2001 7:55:31 AM
quote:
Original post by derwiath

Hello.

I tried it out in vc++ 6 now and it seems to
be possible to forward an enum just as you forward a class or
a struct.

enum ETMyEnum;

You don''t even have to use references or pointer to the enum
in the function headers because the compiler knows that an enum always is an int.

------------------------------
- Derwiath -


Weird, I tried this with BCB5 and I got a compiler error "ETMyEnum has to be defined enum already". Seems that Borland''s compiler doesn''t support enum-forwarding...?

@amag: I think, if my enum belongs to a certain header, I should be able to put it there. Just for logical encapsulation. Hmm, I already considered using simple int-parameters to work around to this problem. Header dependency in a large project can really be annoying. Little change -> fat compile time

It seems that I find more and more lacks of c++.
- Inline Functions must be defined in *.h
(This can be a serious problem!)
- switch-statement is very unflexible (compared to Delphi)
(Ok, I know it''s also faster)
- Compile times... yawn... (Delphi is much faster).
Is code optimizing of c++ really *that* better?
- No initialisation of a struct-var in function call.
- No local functions!!! Have to use an ugly and unflexible
hack to realize them.
- No standard set - support. (-> Delphi''s in-operator)

Ok, considering the good things with c++, it''s still my favourite .

Wunibald




(Computer && !M$ == Fish && !Bike)
I know I''m starting to sound like a broken record, but I just read "Large-Scale C++ Software Design" by Lakos, and he addresses a lot of the issues you bring up, including the enum issue.

His argument is that since enums have internal linkage, they must be in the header file in order to be used by clients; they inherently create compile-time coupling. The solution is to remove it.

He gives the example of 3 kinds of enumerations:
  // whatever.hclass Whatever{private:  enum { DEFAULT_TABLE_SIZE = 100 }; // 1public:  enum { DEFAULT_BUFFER_SIZE = 200 }; // 2  enum Status { A, B, C, D, E, F }; // 3  Status doIt (); // function that uses Status};  


enum #1 shouldn''t even be there--it should be in whatever.cpp or a static const member of the class.

enum #2 could be made a private static const class member, and you could have an accessor function to get its value. Quoting the author, "As with most insulation techniques, we pay a price in runtime performance for the reduced coupling." If you can inline the accessor, a smart compiler might not give you a hit in performance.

enum #3 is definitely part of the interface, and there''s basically no way to get around having it in there. The author suggests not having a single global set of status value that everybody depends on, but to have the enums be class-specific.

quote:

It seems that I find more and more lacks of c++.
- Inline Functions must be defined in *.h
(This can be a serious problem!)


Untrue. You can inline free functions in your .c file. If you have member functions you want to be inlinable, their definitions must be in the .h file. In order to reduce compile-time coupling, I try to avoid that situation.
quote:

- switch-statement is very unflexible (compared to Delphi)
(Ok, I know it''s also faster)
- No initialisation of a struct-var in function call.
- No standard set - support. (-> Delphi''s in-operator)


I don''t know Delphi, so I can''t help you out there. In all fairness, switch is a feature of C (i.e. not "new" with C++).
quote:

- Compile times... yawn... (Delphi is much faster).
Is code optimizing of c++ really *that* better?


Yes. Look at a breakdown of what languages are used to build professional applications. The more complicated the task, the more people use C++.
quote:

Is code optimizing of c++ really *that* better?



No. Delphi optimizes just as good as your average C++ compiler.
Advertisement
quote:
Original post by Wunibald

- Inline Functions must be defined in *.h
(This can be a serious problem!)



As far as I know you can define infline functinos in the CPP file but you have to use the inline keyword - see MSDN for more info.
quote:

Untrue. You can inline free functions in your .c file

..

As far as I know you can define infline functinos in the CPP file but you have to use the inline keyword - see MSDN for more info.


How is that possible? Declaration and implementation of inline functions cannot be seperated into .h and .cpp.

I like to know how you guys do it.
@Stoffel: You''re right about the inline-functions. I was talking about *member*-inline-functions indeed.
Bad thing about those enums... . Actually, I didn''t want to put my enum in a class. I''d like to use it to access a constant array, that is defined in my *.h file.
But anyway, I''ll be rid of my job as a programmer in one month.
I''ll live in a monastery for about 10 years to recover .

Wunibald
(Computer && !M$ == Fish && !Bike)
quote:
Original post by Void
How is that possible? Declaration and implementation of inline functions cannot be seperated into .h and .cpp.
I like to know how you guys do it.


That''s because the function is not declared in the .h file; I was referring to static free function in the cpp file (static = internal linkage, free = not part of a class).

  // main.cppinline static bool isPowerOfTwo (int a){  return a == (a & -a); // compliments to flipcode}int main (){  //...  if (isPowerOfTwo (someVar)) // code is replaced inline, no call  //...}  


You can''t say anything about the function in the .h file because it specifically has internal linkage. If you have an inline function that you would like multiple modules to use (such as a class member), then yes, you must put the implementation in the .h file. This is why I like to avoid that situation (though for simple accessor functions, it''s usually appropriate).

This topic is closed to new replies.

Advertisement