![]() |
Friends in inheritance
Hello,
There is a rather annoying problem in my code, and I just can't get to the bottom of it. I have a class, A, and another one, B, which inherits from A. Now, A has a friend class, C, which is declared inside it. Whenever I want to use C's public constructor from within a method of B, I get errors like "expected type-specifier", and "expected ';'". I know friends are not inherited, so I made C a friend of B, too. Which changes absolutely nothing. Always the same errors. What am I doing wrong? If I call C's constructor like : A::C(...), or simply C(...), I get the same errors. Have any ideas? Thanks |
Re: Friends in inheritance
My guess, not having seen code that illustrates the problem, is that you've left out a semi-colon or a closing brace somewhere in code before where the error is reported.
Or - less likely - you're working with template classes, for which the rules are slightly different, and you've left out a "typename" keyword at a point where you need it. |
Re: Friends in inheritance
Nice guess, I AM working with template classes. OK, here's the simplified code to illustrate what is happening :
:
Now, here's the problem : :
generates errors. So does : :
EVEN IF, before declaring the class A, I declare B like so : :
and put, in class C : :
When using method1, I get the same errors. What should I do? How can B access C's constructor? |
Re: Friends in inheritance
It is usually better if you provide a SMALL but COMPLETE code sample that illustrates your problem. By paraphrasing, as you've done, you force people to guess at your problem because you may have left out key details.
My primary guess is that you've encountered one of the obscure limitations with templates in the current C++ standard -- fixing it is on the list of proposals for a future version of the standard. To make use of A<T>::C within a member function of B<T> you need to implement the member function inline (i.e. within the declaration of B<T>). For example; :
template <typename T> class B : public A<T> {:
template <typename T> B<T>::method1(...) {But, in any event, the problem has nothing to do with friendship (friendship affects accessibility, not the sort of thing you're seeing). Without an actual code sample that illustrates your problem, I can't/won't guess further. |
Re: Friends in inheritance
First of all, thank you for your help.
Second, here is the actual code : :
generates the following errors at 'new Element" : error : expected type-specifier before 'Element' And if I write : :
i get: error : expected type-specifier So, my idea was to put :
inside the class Element, and declaring DerivedList before LinkedList like so : :
and the compiler gives the very same errors as before. What do you think? |
Re: Friends in inheritance
Yep; you're running into the issue of dependant template types (instantiation of DerivedList template relies on instantiation of the LinkedList template, .... etc and the compiler is allowed to defer instantiation of any of those templates until it is too late).
In your particular case, a workaround I suggest is providing a copy constructor for LinkedList<> with the same body as your current DerivedList<> copy constructor, and not explicitly implement the DerivedList copy constructor. (the compiler generated copy constructor for DerivedList would automatically invoke the inherited one). Other than that, you need to inline ALL your definitions (no reliance on forward declaration of the Element class, no "out of line" implementation of copy constructors, etc). The philosophy is making sure that the compiler has access to all information it needs when .... eventually ... it finds it needs to instantiate templates. Friend declarations are not a solution to the problem: they just influence what code is allowed to access something. If it was, you could just make everything public and the problem would go away. More generically (C++ template issues aside) I'm failing to work out how your design makes sense for a linked list. Your LinkedList contains a pointer to an element, and presumably each element needs a pointer to the LinkedList that contains it. That circular dependancy does not make sense to me. Generally I would expect the nodes of a linked list (your Element) would contain data (the info member), and one or more pointers to other nodes. No need for a pointer back to the containing LinkedList. Practically, I'd also use a std::list<> anyway, rather than rolling my own linked list template as well. I assume you're doing this for learning purposes. |
Re: Friends in inheritance
Thank you ever so much for these tips.
As for your remarks about the implementation of the list, I agree with you. This code is not mine, it is given by an educator, who wants us to further enhance it. I know there are many much simpler ways (and more clearer ways) to implement a linked list, the aim of this exercise was to make us familiar with friends in inheritance. But you are absolutely right : this code is not efficient at all, and moreover, it is very unclear. Having said this, I thank you once more for outlining what should and should not be done when using template classes like this...so much I didn't know. |
Re: Friends in inheritance
I was playing around with writing data structures in C++ a while ago. I hope this is somewhat useful.
:
|
Re: Friends in inheritance
Wow thanks! I'm sure I'll be able to put it to use!
|
| All times are GMT -5. The time now is 4:00 AM. |
Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC