Can your header file structure solve this cyclic dependency?

Started by
14 comments, last by Nemesis2k2 19 years, 1 month ago
Certainly C++ isn't the perfect language. But do you really want to work with some sort of convoluded include system just so you can save a few cycles with inlined functions? Its unfortunate that inline functions pollute interface-implementation separation, but there's really little you can do about that short of hacking your way around it which I guess is what you're trying to do. It just doesn't seem like you're going to find a clean solution that anybody would want to work with.
Advertisement
Quote:Certainly C++ isn't the perfect language. But do you really want to work with some sort of convoluded include system just so you can save a few cycles with inlined functions? Its unfortunate that inline functions pollute interface-implementation separation, but there's really little you can do about that short of hacking your way around it which I guess is what you're trying to do. It just doesn't seem like you're going to find a clean solution that anybody would want to work with.

The whole header system is a hack. I'm doing my best to minimize the amount of hacking I have to do on top of that. This is about structure. I'm designing an overall system which I feel comfortable working with, which lacks stupid problems like the one outlined here. I have a solution to this problem, and it's no more ugly than an include guard, which people seem to take for granted. It can't solve everything though. Namespaces are limited to a fraction of their potential power, as well as requiring some godawful hacks to implement in an at all abstract way. These problems cannot be solved with any header system. They are the result of a fundamental flaw with the header system itself.
You could always make the functions not inline, then use a compiler that supports 'link-stage inlining'(not sure of proper name) as I believe VS.Net 2002 and later do.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
templates to the rescue..

I still think the problem is your choice of design. You have two closely related classes that are interconstructable, why not make them the same class?

template<std::size_t size>struct Vector{float elements[size];Vector(const Vector<size>&){...} // for vectors of the same sizetemplate<std::size_t anothersize>Vector(const Vector<anothersize>&){...} //for vectors of different sizes};


Problem solved? No more cyclic dependancy in the headers, there is only one header, both functions are inline.
Hi,

this is my solution to your problem:

Vec3.h:
#ifndef _Vec3_h_#define _Vec3_h_class Vec4;class Vec3{public:    inline void somefunc(Vec4& vec4);    float x,y,z;};#include "vec3.inl"


vec3.inl:
#include "Vec4.h"void Vec3:somefunc(Vec4& vec4){}


Vec4.h:
#ifndef _Vec4_h_#define _Vec4_h_class Vec3;class Vec4{public:    inline void somefunc(Vec3& vec3);    float x,y,z,w;};#include "vec4.inl"


vec4.inl:
#include "Vec3.h"void Vec4:somefunc(Vec3& vec3){}


hope this helps.
“Always programm as if the person who will be maintaining your program is a violent psychopath that knows where you live”
Quote:I still think the problem is your choice of design. You have two closely related classes that are interconstructable, why not make them the same class?

No. Most definately no. First of all, I want to be able to use the .x, .y, .z, etc specifiers to access elements. Secondly, I don't want to have to use template specialization in order to implement all my functions.

Templates do solve this problem though. Remember that no code is created from a template until an object is created of that type. I can have this contradiction exist in two dependant templated classes, and it'll still work, because the template isn't parsed until I try and use it later on, by which time, both types have been fully defined. When I originally started thinking about this problem, I overlooked this, so I thought this would basically prevent two templated classes with this kind of dependency existing at all, because templated classes have to have all their functions defined in a header file. I was quite pleasently surprised to find this wasn't the case.

Quote:Hi,

this is my solution to your problem:

That is an awesome idea, and the neat solution I was looking for. Rather than putting the #include inside the inline file though, I'd put it just above the include for the inline file itself. This keeps an inline file plain and simple, and means I can just make a small modification to the standard template I create a header from. Cheers dude, I can't believe I overlooked this simple solution.

This topic is closed to new replies.

Advertisement