Topic: mandate virtual


Author: "Ken Hagan" <K.Hagan@thermoteknix.co.uk>
Date: 2000/11/15
Raw View
I wish I had my copy of "Generative Programming" with me right now,
to check the details, but there is an interesting idiom which allows
a template author to let clients choose between static and dynamic
binding for a method in a template instatiation. Roughly...

  struct Static { void fred(); }; // no body provided for fred()
  struct Dynamic { virtual void fred() = 0; };

  template<typename T> struct Component : public T { void fred(); };

Now Component<Static> will have a non-virtual member "fred" whereas
Component<Dynamic> will have a virtual one.

The idiom would clearly be broken if repeating "virtual" were either
mandatory or prohibited. (This equally applies to the "override"
keyword that some people have suggested in this context.)

Is the idiom useful? I think so, particularly in the presence of
other metaprogramming templates like IF<>. However, I must confess
that I felt a little disappointed when I first read about it. It
seemed a shame that someone had found a good use for something
I'd always considered a defect in the language.

"Andrew J Robb" wrote...
> class A
> {
> public:
>   virtual void fred();
> };
>
> class B : public A
> {
> public:
>   void fred();
> };
>
> The above example is an obscure way of declaring that B::fred() is
> virtual. And may be changed in B by changing A::fred() from being
> virtual. This is not clear.
>
> Please, consider making "virtual" mandatory in derived classes if
> a method is already virtual in a base class.


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: David R Tribble <david@tribble.com>
Date: 2000/11/16
Raw View
David R Tribble wrote:
>> For example, it would make it clearer when declaring a class derived
>> from B that the intent was to have (or not to have) a virtual
>> member function:
>>
>>     class C: public B
>>     {
>>     public:
>>         virtual void  fred();  // Error if B::fred() not virtual,
>>                                // which is not clear from class B
>>                                // declaration above
>>     };

Ron Natalie wrote:
> Why shouldn't C::fred() be allowed to be virtual if B::fred() isn't?

Um, it can.  What I meant to say, as per the original suggestion,
is that the 'virtual' specifier should be required on the
declaration of any virtual function, inherited or not.

So a better example would be:

    class B
    {
    public:
        virtual void  fred();
    };

    class C: public B
    {
    public:
        void  fred();    // Error, missing 'virtual' modifier,
                         // since B::fred() is virtual
    };

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: "Sebastian Moleski" <smoleski@surakware.com>
Date: 2000/11/16
Raw View
"David R Tribble" <david@tribble.com>:
...
> So a better example would be:
>
>     class B
>     {
>     public:
>         virtual void  fred();
>     };
>
>     class C: public B
>     {
>     public:
>         void  fred();    // Error, missing 'virtual' modifier,
>                          // since B::fred() is virtual
>     };

Well, if virtual is not automatically inherited anymore, this could mean the
definition of a new function called fred which has no relation to the base
classes' fred.

sm


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: "Andrew J Robb" <news.@.screaming.net@news.server.worldonline.co.uk>
Date: 2000/11/14
Raw View
class A
{
public:
  virtual void fred();
};

class B : public A
{
public:
  void fred();
};

The above example is an obscure way of declaring that B::fred() is virtual.
And may be changed in B by changing A::fred() from being virtual. This is
not clear.

Please, consider making "virtual" mandatory in derived classes if a method
is already virtual in a base class.


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: James Dennett <james@evtechnology.com>
Date: 2000/11/14
Raw View
Andrew J Robb wrote:
>
> class A
> {
> public:
>   virtual void fred();
> };
>
> class B : public A
> {
> public:
>   void fred();
> };
>
> The above example is an obscure way of declaring that B::fred() is virtual.
> And may be changed in B by changing A::fred() from being virtual. This is
> not clear.
>
> Please, consider making "virtual" mandatory in derived classes if a method
> is already virtual in a base class.

Clearly that would break much existing code, so there is likely to be
opposition to it.  Currently the keyword "virtual" has no effect (other
than acting as documentation and, as you say, a safeguard against changes
to base classes) so some might consider its use in class B to be "noise"
given current C++ rules.

Compilers are already free to issue a warning if you hide (rather than
override) a base class member function.

I can't say that I particularly like the rules which say that virtualness
is implicitly inherited, but I can't see them changing unless there is a
clear demonstration of danger in the current rules.  The C++ language will
never be able to provide complete protection against code being broken by
careless changes to base classes; base classes should be present to specify
interface (possibly with partial implementation), so it makes little sense
to think that they can be changed without considering the effect on derived
classes.

-- James Dennett <jdennett@acm.org>

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: David R Tribble <david@tribble.com>
Date: 2000/11/14
Raw View
Andrew J Robb wrote:
>
> class A
> {
> public:
>   virtual void fred();
> };
>
> class B : public A
> {
> public:
>   void fred();
> };
>
> The above example is an obscure way of declaring that B::fred() is
> virtual.  And may be changed in B by changing A::fred() from being
> virtual. This is not clear.
>
> Please, consider making "virtual" mandatory in derived classes if a
> method is already virtual in a base class.

This would solve many problems, but not all.  I think it's a good
idea, if for no other reason than it makes it more obvious to
[maintenance] programmers what the intent is.

For example, it would make it clearer when declaring a class derived
from B that the intent was to have (or not to have) a virtual
member function:

    class C: public B
    {
    public:
        virtual void  fred();  // Error if B::fred() not virtual,
                               // which is not clear from class B
                               // declaration above
    };

However, it still would not prevent accidentally declaring a
virtual member function that does not match the base function it
is intended to override:

    class C2: public B
    {
    public:
        virtual void  fred(int);   // Different from B::fred()
    };

For this situtation, others before have suggested an explicit
keyword such as 'override' to indicate the intent:

        [virtual] override void  fred(int);
            // Error if there is no fred() in the base classes

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Ron Natalie <ron@sensor.com>
Date: 2000/11/14
Raw View

David R Tribble wrote:
>
>
> For example, it would make it clearer when declaring a class derived
> from B that the intent was to have (or not to have) a virtual
> member function:
>
>     class C: public B
>     {
>     public:
>         virtual void  fred();  // Error if B::fred() not virtual,
>                                // which is not clear from class B
>                                // declaration above
>     };

Why shouldn't C::fred() be allowed to be virtual if B::fred() isn't?
>

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]