Topic: Bug or feature? Please help...


Author: Philippe Nobili <pnobili@imaginet.fr>
Date: 1998/01/01
Raw View
Vlad Vinogradsky wrote:
>
> Code snippet below doesn't compile with VC++ 5.0. I worked through CD2 and
> available C++ textbooks trying to determine if this is a compiler bug or
> normal behavior. Failed to find any clear indication. Can't see anything
> wrong with the code. Any ideas would be appreciated.
>
> #include <iostream>
> class PSuper
> {
> public:
>  virtual void Foo() = 0;
>  virtual void Zoo() = 0;
> };
>
> template<class T>
> class PSub : public PSuper
> {
> public:
>  virtual void Foo(int) = 0;
> };
>
> template<class T>
> class Sub : public PSub<T>
> {
> public:
>  void Foo();
>  void Foo(int);
>  void Zoo();
> };
>
> template<class T>
> void Sub<T>::Foo()
> {
>  std::cout << "Sub<T>::Foo()" << std::endl;
> }
>
> template<class T>
> void Sub<T>::Foo(int)
> {
>  std::cout << "Sub<T>::Foo(int)" << std::endl;
> }
>
> template<class T>
> void Sub<T>::Zoo()
> {
>  std::cout << "Sub<T>::Zoo()" << std::endl;
> }
>
> int main(int,char** argv)
> {
>  PSub<int>* pObj = new Sub<int>();
>  pObj->Zoo();
>  pObj->Foo(); // 1. fails to compile with an error message: Foo() doesn't
> take 0 parameters.
> return 0;
> }

Hi,

I think your compiler is right. Methods declared in different scopes
cannot overload ( it does not matter whether this method is virtual or
not ). Even with a simpler example:

class A {
 public :
 A() {}
 virtual ~A() {}

 void tryIt() {}

} ;

class B : public A {
 public :
 B() {}
 ~B() {}

 void tryIt(int) {}
} ;

main(int argc,char *argv[]) {

 B* b = new B() ;
 b->tryIt() ;

}

This should fail if your compiler correctly implement C++ standard.
Hope this helps,
                 Philippe.

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Oleg Zabluda <zabluda@math.psu.edu>
Date: 1998/01/01
Raw View
In comp.std.c++ Vlad Vinogradsky <vinogradsky@ibm.com> wrote:
: Code snippet below doesn't compile with VC++ 5.0. I worked through CD2 and
: available C++ textbooks trying to determine if this is a compiler bug or
: normal behavior. Failed to find any clear indication. Can't see anything
: wrong with the code. Any ideas would be appreciated.

: #include <iostream>
: class PSuper
: {
: public:
:  virtual void Foo() = 0;
:  virtual void Zoo() = 0;
: };

: template<class T>
: class PSub : public PSuper
: {
: public:
:  virtual void Foo(int) = 0;
: };

Bad idea. Psub::Foo(int) hides Psuper::Foo(). It does not
override it. PSub IS_NOT_A Psupper anymore. That's why
pObj->Foo() does not compile.

[ template<class T> class Sub is snipped, because it's irrelevant ]
[ to your problem. See later                                      ]

: int main(int,char** argv)
: {
:  PSub<int>* pObj = new Sub<int>();
:  pObj->Zoo();
:  pObj->Foo(); // 1. fails to compile with an error message: Foo() doesn't
: take 0 parameters.

C++ is a statically typed language. The type of pObj is Psub<int>*
(should really be at least Psub<int>* const). PSub<int> does not
have a member Psub<int>::Foo(), because you immorally hid it with
Psub<int>::Foo(int). At this point, the compiler does not care at all
what was on the right hand side of the initialization.

: return 0;
: }

Oleg.
--
Life is a sexually transmitted, 100% lethal disease.

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]





Author: Nick Woebcke <nwoebcke@vividusa.com>
Date: 1998/01/01
Raw View
Vlad Vinogradsky wrote:
>
> Code snippet below doesn't compile with VC++ 5.0. I worked through CD2 and
> available C++ textbooks trying to determine if this is a compiler bug or
> normal behavior. Failed to find any clear indication. Can't see anything
> wrong with the code. Any ideas would be appreciated.
>
> template<class T>
> class Sub : public PSub<T>
> {
> public:
>  void Foo();
>  void Foo(int);
>  void Zoo();
> };
>
> int main(int,char** argv)
> {
>  PSub<int>* pObj = new Sub<int>();
>  pObj->Zoo();
>  pObj->Foo(); // 1. fails to compile with an error message: Foo() doesn't
> take 0 parameters.
> return 0;
> }
>
> --
> Vlad Vinogradsky
> RDA Consultants, Ltd. (www.rdaconsultants.com)
> ---
Vlad,

It looks like a compiler problem to me.  What a shock!  I would say
rename Foo() to something else (like Boo()) or combine Foo() and
Foo(int) to Foo(int i=-1) so that you can call Foo() without any
parameters.  That is my pragmatic solution.

-- Nick


--
+------------------------------+-------------------------------------+
| Nick Woebcke                 |   work: nwoebcke@vividusa.com       |
| Vivid Technologies, Inc.     |   home: nickw@thecia.net            |
| Woburn, MA 01801             |                                     |
+--------------------------------------------------------------------+
| Eliminate Corporate Welfare, Regain Free Speech & Accountability:  |
|      U.S. Government   -   Big Campaign $$$   ~=   Democracy       |
+--------------------------------------------------------------------+

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]





Author: steagall@deltalogic.com (Bob Steagall)
Date: 1998/01/01
Raw View
On 31 Dec 97 01:17:49 GMT, "Vlad Vinogradsky" <vinogradsky@ibm.com> wrote:

> Code snippet below doesn't compile with VC++ 5.0. I worked through CD2 and
> available C++ textbooks trying to determine if this is a compiler bug or
> normal behavior. Failed to find any clear indication. Can't see anything
> wrong with the code. Any ideas would be appreciated.
>
> #include <iostream>
> class PSuper
> {
> public:
>  virtual void Foo() = 0;
>  virtual void Zoo() = 0;
> };
>
> template<class T>
> class PSub : public PSuper
> {
> public:
>  virtual void Foo(int) = 0;
> };

If a base class has a function name that's declared or overloaded, then
re-declaring that function name in a derived class will hide all the
base-class versions.  When you declare a new version of Foo() in PSub<T>,
you are hiding the version declared in the base class PSuper.

That being said, I don't see why the compiler doesn't find Sub<T>::Foo()
in your example.  Perhaps the compiler does not like to see a
re-re-declaration for a virtual function in a derived class that was hidden
by a base class.

Anyway, to fix the problem with VC++ 5:

    template<class T>
    class PSub : public PSuper
    {
    public:
        virtual void Foo() = 0;
        virtual void Foo(int) = 0;
    };

Then all is right with the world ;-)

--Bob

====================================================================
Bob Steagall                                 steagall@deltalogic.com
DeltaLogic, Inc.                           http://www.deltalogic.com
1537 Kew Road                                   Voice (216) 321-8200
Cleveland Hts, OH 44118-1204                    Fax   (216) 321-6976

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]





Author: Pete Becker <petebecker@acm.org>
Date: 1998/01/02
Raw View
Vlad Vinogradsky wrote:
>
> Code snippet below doesn't compile with VC++ 5.0. I worked through CD2 and
> available C++ textbooks trying to determine if this is a compiler bug or
> normal behavior. Failed to find any clear indication. Can't see anything
> wrong with the code. Any ideas would be appreciated.
>
> [code snipped]
>
> int main(int,char** argv)
> {
>  PSub<int>* pObj = new Sub<int>();
>  pObj->Zoo();
>  pObj->Foo(); // 1. fails to compile with an error message: Foo() doesn't
> take 0 parameters.
> return 0;
> }

Get rid of the templates: they're confusing you, and they're irrelevant.
If you still don't see what's happening, ask again. The compiler is
right.
 -- Pete

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Vlad Vinogradsky" <vinogradsky@ibm.com>
Date: 1997/12/31
Raw View
Code snippet below doesn't compile with VC++ 5.0. I worked through CD2 and
available C++ textbooks trying to determine if this is a compiler bug or
normal behavior. Failed to find any clear indication. Can't see anything
wrong with the code. Any ideas would be appreciated.

#include <iostream>
class PSuper
{
public:
 virtual void Foo() = 0;
 virtual void Zoo() = 0;
};

template<class T>
class PSub : public PSuper
{
public:
 virtual void Foo(int) = 0;
};

template<class T>
class Sub : public PSub<T>
{
public:
 void Foo();
 void Foo(int);
 void Zoo();
};

template<class T>
void Sub<T>::Foo()
{
 std::cout << "Sub<T>::Foo()" << std::endl;
}

template<class T>
void Sub<T>::Foo(int)
{
 std::cout << "Sub<T>::Foo(int)" << std::endl;
}

template<class T>
void Sub<T>::Zoo()
{
 std::cout << "Sub<T>::Zoo()" << std::endl;
}

int main(int,char** argv)
{
 PSub<int>* pObj = new Sub<int>();
 pObj->Zoo();
 pObj->Foo(); // 1. fails to compile with an error message: Foo() doesn't
take 0 parameters.
return 0;
}

--
Vlad Vinogradsky
RDA Consultants, Ltd. (www.rdaconsultants.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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Robert A. Rice" <ricer@tis.com>
Date: 1997/12/31
Raw View
Vlad Vinogradsky wrote:

> Code snippet below doesn't compile with VC++ 5.0. I worked through CD2 and
> available C++ textbooks trying to determine if this is a compiler bug or
> normal behavior. Failed to find any clear indication. Can't see anything
> wrong with the code. Any ideas would be appreciated.
>
> <code snipped>

Vlad,

Even though you are pointing a PSub<int> * at a Sub<int> object, a
PSub<int> * may point at an object which is an instance of any subclass
of PSub<int>.  In PSub<int>, there is no Foo() method declaration.
Therefore, the invocation

pObj->Foo();

is not guaranteed to work, and so is flagged as an error by the
compiler.
You need to declare Foo() in PSub<int>, probably as pure virtual.

Bob Rice
ricer@gte.net


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]