问题
(First and foremost, sorry for my English)
In order to avoid the syntactic limitation of circular dependence, I want to know if the following proposed solution is really a solution or if it has more disadventages than adventages (let's me suposse that this mutual dependence is inavoidable):
Original situation:
class B;
class A
{
B needed;
};
class B {};
Output:
B has an incomplete type.
"Solution":
template<typename T = class B>
class tricky_A
{
static_assert(is_same<T, B>::value, "Too tricky!!");
T needed;
};
class B {};
using A = tricky_A<>;
int main()
{
A a; // At the instantiation point, B isn't an incomplete type.
}
Output:
No problems.
The common solution is to make use of pointers, but I see two problems when you really don't need them:
1) If you decide to retain pointer to other local objects, you should be sure (or the user of your class should be sure) that the life of your object is shorter than the life of the "retained" object.
2) If you decide to deal with dynamic memory, you should spend time reserving and destructing memory, and moreover it forces you to deal with exception handling, in order to make your code exception safe.
*) Longer code; smaller readability; harder mantenance; etc.
Should I use this "solution" or better to search other one?
EDIT: You are all right. This isn't a real circular dependence, so, there isn't anything to ask. This question can be closed.
EDIT2: A better question here.
回答1:
I think the use of pointers (and I agree with @Andy Prowl RE: smart pointers) is the preferred solution. Regarding your point about Longer code, smaller readability, harder maintenance - your "tricky" solution, while clever, violates all those tenants - it's longer, harder to read, and harder to maintain. An entry to mid-level C++ developer should know how to deal with pointers and smart pointers, however it is hard to expect them to understand the template solution you proposed.
I also do not see the circular dependency in your example; I'll assume that B
also depends on A
, though.
Important things to remember when dealing with this kind of design are:
- Separating header and body is helpful
- Prefer to do
#includes
in the following order: body#includes
, forward-reference#includes
, and finally (if necessary), header#includes
回答2:
The premise on your design is wrong. Since there is no circular dependency in your code, there is nothing to fix (other than locating the definition of B
before A
) and no extra work needs to be done.
If you fix your test case to contain a real circular dependency, you will find out that your solution does not solve it. So basically you have more code that is more complex and still the same problem.
Also note that the correct way of handling a circular dependency is by breaking it. Once the circular dependency is gone, the need to manage it is also gone. There are very few good designs that contain a real circular dependency.
来源:https://stackoverflow.com/questions/15953918/to-what-extent-can-be-this-a-bad-practice-circular-dependence