By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,996 Members | 892 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,996 IT Pros & Developers. It's quick & easy.

Is this valid C++?

P: 16
The following code compiles on the latest VC++, not EDG or MINGW.

Expand|Select|Wrap|Line Numbers
  1. template <typename T>
  2. class Base
  3. {
  4. public:
  5.     void doSomething(); 
  6. };
  7.  
  8. template <typename T>
  9. class Derived : public Base<T>
  10. {
  11. public:
  12.     using Base::doSomething; // <-- valid?
  13.     // or do you have to do this?
  14.     //using Base<T>::doSomething;
  15.  
  16.      void doSomething(int i);
  17. };
  18.  
  19.  
  20. int main()
  21. {
  22.     return 0;
  23. }
I tried to consult the standard, but couldn't find a definite answer.
Aug 14 '07 #1
Share this Question
Share on Google+
10 Replies


weaknessforcats
Expert Mod 5K+
P: 9,197
What are you trying to do???

In Derived there is a method:

void doSomething(int i);

which hides Base::doSomething().

If you are using polymorphism, this is an error since Derived::doSomething() will never be called using a Base pointer or reference.

On the other hand, if you are doing object-based programming, then this would be OK so long as Derived::doSomething() did not have to internally call Base::doSomething() to recover the the code in Base that is being hidden by Derived.
Aug 14 '07 #2

P: 16
What are you trying to do???

In Derived there is a method:

void doSomething(int i);

which hides Base::doSomething().

If you are using polymorphism, this is an error since Derived::doSomething() will never be called using a Base pointer or reference.
Actually the code is not really supposed to do anything, I just tried to make my code example as concise as possible. The intent is to grant access to the doSomething() method that would otherwise be hidden from a Derived object, like so:

Expand|Select|Wrap|Line Numbers
  1. int main()
  2. {
  3.     Derived<int> d;
  4.     d.doSomething(); // <-- calls Base::doSomething(), 
  5.                      //need a using-declaration for this
  6.  
  7.     d.doSomething(42); // <-- calls Derived::doSomething(int)
  8.  
  9.     return 0;
  10. }
I guess I should have been more specific. My question is about the syntax of the using-declaration: Is it valid C++ to write "using Base::doSomething()" without supplying a template parameter or do you have to write "using Base<T>::doSomething()"?
Aug 14 '07 #3

weaknessforcats
Expert Mod 5K+
P: 9,197
"using Base::doSomething()" without supplying a template parameter or do you have to write "using Base<T>::doSomething()"?
You use the one that compiles.

just tried to make my code example as concise as possible. The intent is to grant access to the doSomething() method that would otherwise be hidden from a Derived object,
You can code this way. It's not recommended and can set you up for an ambiguous call. But I have seen this done:

Expand|Select|Wrap|Line Numbers
  1. void Derived::doSomething(int i)
  2. {
  3.     Base::doSomething(i);   //recover base class code
  4.     //
  5.     //TODO: Add Derived code here
  6. }
  7.  
The problem is that it is not clear if the call to Base::doSomething() is a pre-condition or a post-condition. That is, do you call it before the Derived code or after the Derived code. That ambiguity points to a design weakness. Any weakness should be fixed in the design so you don't have to do this.
Aug 14 '07 #4

RRick
Expert 100+
P: 463
What is the error message you are getting. Is it the same for both compilers? Templates have changed a lot in the last few years and templates are the root of many syntax problems. For example typename is a new construct and some compilers can't handle it.

The doSomething's in both classes are different. The base class and derived class define separate/different doSomething methods (based on the parameters defined). This is perfectly legal.

From the derived class you can access the base class and derived class doSomething. You don't need to worrry about defining anything extra in the derived class because:



  1. The doSomething in Base is public, and
  2. You inherit the base class as public.
You can get rid of all the "using" stuff in your code. Using only affects namespaces, not methods.
Aug 14 '07 #5

P: 16
Thanks for your reply. I realize, of course, that my example code demonstrates questionable design. In general I would not use public inheritance unless I intend to use the base class polymorphically, and certainly not if it doesn't have a single virtual function/dtor.

Even if my question was only related to the syntax of the using-declaration, you bring up some good points related to class design that I believe more people than me can learn from.
Aug 14 '07 #6

weaknessforcats
Expert Mod 5K+
P: 9,197
In general I would not use public inheritance unless I intend to use the base class polymorphically,
That's not the reason for public inheritance. Public inheritance is used when you want the interface of the base class to become part of the interface of the derived class.

Polymorphism is usually implemented using private inheritance. The derived class private methods override the base class private virtual methods. The base class public methods are the interface to the hierarchy and they are not supposed to be virtual.
Aug 15 '07 #7

P: 16
Polymorphism is usually implemented using private inheritance.
I agree that what you describe is a form of polymorphism, but I disagree that it is the most common form. If you use private inheritance, only the members of Derived (and friends) can use the class polymorphically in place of a Base class.

Inheriting publicly with the Derived class overriding Base's virtual functions we can use a Base* polymorphically through late binding, and I'd say that's how polymorphism is usually implemented.
Aug 15 '07 #8

RRick
Expert 100+
P: 463
First of all, polymorphism is only supported through public and protected inheritance. Private things remain private and can not be expanded, accessed, or polymorphized(?word?) from derived classes.

This is why I make my object's methods and data protected instead of private. This allows the derived classes access to the internals. I agree this could be dangerous, but I make a distinction between public access of an object and derived objects. Derived objects are suppose to know what they do, whereas the public must be "protected" from the internals. In my designs, the only thing that is private are things that I definitely don't want the derived class to mess with.

The discussion here seems to be whether public vrs protected inheritance is correct/normal/the best. I think it depends on the use. If you want all of the base class functionality to be publicly available, then inherit it publicly. Otherwise, it must be inherited as protected, and the derived class releases specific functionality itself.

The second approach is what shows up mostly in the literature (i.e. book I have read), but in practice I've seen both. Sometimes I lean on public inheritance simply through laziness and time constraints, but the choice is really application specific.
Aug 15 '07 #9

RRick
Expert 100+
P: 463
I went back and took a second look and realized I was definitely confused in my reply. For the record, you can inherit public, protected or private. Private inheritance tends to be pretty rare (at least from what I've seen) but I suppose it has its uses.

I still stand by my last two paragraphs. Here, I assume the main difference and discussion is between public verus protected or private access to an object.
Aug 16 '07 #10

P: 16
I went back and took a second look and realized I was definitely confused in my reply. For the record, you can inherit public, protected or private. Private inheritance tends to be pretty rare (at least from what I've seen) but I suppose it has its uses.
Private inheritance is (or should be) used if you want to use your base class as an implementation detail in your subclass, whereas public inheritance is used to model IS-A, per the Liskov Substitution Principle. This is a prerequisite for being able to use the subclass polymorphically in place of a base. (If you inherit privately you have to explicitly grant friendship to every function and class that wants the same behavior).
Aug 16 '07 #11

Post your reply

Sign in to post your reply or Sign up for a free account.