Topic: Name conflicts from inherited classes


Author: Srinivas Vobilisetti <Srinivas.Vobilisetti@mci.com>
Date: 1997/08/18
Raw View
Rune Christensen wrote:
>
> It seems to me it's getting quite normal to defined 'interfaces' using
> classes with pure virtual functions, and object/server implementing /
> offering such interfaces by letting the class of the object inherit
> from all of the interfaces, and implementing their methods.
>
> The problem is that the naming of the methods in the interfaces is in
> the context of the interface - e.g. a method called GetID() may be
> quite logical in such a context. When the server is implemented it is
> quite possible that name clashes might occur:
>   A method executed through one interface should not necessarily be
> the same as a, equivalent named, method executed through another
> interface - the two interface definitions shouldn't need to be 'aware'
> of each other just because they _may_ be implemented by the same
> server.
>
> Example:
>
> class Interface1
> {
> public:
>    virtual string GetName()= 0;
> };
>
> class Interface2
> {
> public:
>    virtual string GetName()= 0;
> };
>
> class Server: public Interface1, public Interface2
> {
> public
>   virtual string GetName() { return "Server::Interface1"; }
> };
>
> The method Server::GetName is executed whether invoked through
> Interface1 or Interface2. What I'd like to do, is to in the server
> class specify which of the two methods I want to override. E.g. by the
> following syntax:
>
> class Server: public Interface1, Interface2
> {
> public
>   virtual string Interface1::GetName() {return "Server::Interface1";}
>   virtual string Interface2::GetName();
> };
>
> string Server::Interface2::GetName() {return "Server::Interface2";}

You have to add two more classes to solve this ambiguity.

class Interface1_1 : public Interface1 {
public:
   string GetName() { return Interface1_GetName(); }
   virtual string Interface1_GetName() = 0;
};

class Interface2_2 : public Interface2 {
public:
   string GetName() { return Interface2_GetName(); }
   virtual string Interface2_GetName() = 0;
};

class Server : public Interface1_1, public Interface2_2  {
public:
   string Interface1_GetName();
   string Interface2_GetName();
};

Srinivas

> Thus using different implementations depending on what interface a
> method is executed through. I guess this example isn't very good, but
> I don't like that using this 'implementation pattern' requires
> interfaces to know about each other's method names.
>
> Is it, in the current state of the C++ 'standard', possible to specify
> this- which of the same named methods from different base classes to
> override? If not, should it be possible?
>
> Regards,
> Rune Christensen
>
>
>
> ---
> [ comp.std.c++ is moderated.  To submit articles: Try just posting with your
>                 newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
>   comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
>   Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
>   Comments? mailto:std-c++-request@ncar.ucar.edu
> ]
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: ruchrist@online.no (Rune Christensen)
Date: 1997/08/13
Raw View
It seems to me it's getting quite normal to defined 'interfaces' using
classes with pure virtual functions, and object/server implementing /
offering such interfaces by letting the class of the object inherit
from all of the interfaces, and implementing their methods.

The problem is that the naming of the methods in the interfaces is in
the context of the interface - e.g. a method called GetID() may be
quite logical in such a context. When the server is implemented it is
quite possible that name clashes might occur:
  A method executed through one interface should not necessarily be
the same as a, equivalent named, method executed through another
interface - the two interface definitions shouldn't need to be 'aware'
of each other just because they _may_ be implemented by the same
server.

Example:

class Interface1
{
public:
   virtual string GetName()= 0;
};

class Interface2
{
public:
   virtual string GetName()= 0;
};


class Server: public Interface1, public Interface2
{
public
  virtual string GetName() { return "Server::Interface1"; }
};

The method Server::GetName is executed whether invoked through
Interface1 or Interface2. What I'd like to do, is to in the server
class specify which of the two methods I want to override. E.g. by the
following syntax:


class Server: public Interface1, Interface2
{
public
  virtual string Interface1::GetName() {return "Server::Interface1";}
  virtual string Interface2::GetName();
};

string Server::Interface2::GetName() {return "Server::Interface2";}

Thus using different implementations depending on what interface a
method is executed through. I guess this example isn't very good, but
I don't like that using this 'implementation pattern' requires
interfaces to know about each other's method names.


Is it, in the current state of the C++ 'standard', possible to specify
this- which of the same named methods from different base classes to
override? If not, should it be possible?



Regards,
Rune Christensen





---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: marcsh@corel.ca (Marc Sherman)
Date: 1997/08/14
Raw View
In article <33f2698d.317112473@news>, ruchrist@online.no wrote:
[snipped: mixing two interfaces with same-named functions with differing
semantics:]
>
>Example:
>
>class Interface1
>{
>public:
>   virtual string GetName()= 0;
>};
>
>class Interface2
>{
>public:
>   virtual string GetName()= 0;
>};
>

Try this:
class Interface1Wrapper: public Interface1
{
public:
        virtual string GetName1() = 0;
        string GetName() {return GetName1()};
};
class Interface2Wrapper: public Interface2
{
public:
        virtual string GetName2() = 0;
        string GetName() {return GetName2()};
};
class Server: public Interface1Wrapper, public Interface2Wrapper
{
        string GetName1() { return "Interface1 name";}
        string GetName2() { return "Interface2 name";}
};

Calling GetName on a Server object through a pointer to either
Interface1 or Interface2 should return the correct name, while calling
GetName directly on a Server object (or a pointer to Server) should fail
to compile due to the ambiguous function call.

- Marc
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Colin Rafferty <craffert@ml.com>
Date: 1997/08/14
Raw View
Rune Christensen writes:

> [description of problem of name clashes in "interface" classes]

> Example:

> class Interface1
> {
> public:
>    virtual string GetName()= 0;
> };

> class Interface2
> {
> public:
>    virtual string GetName()= 0;
> };


> class Server: public Interface1, public Interface2
> {
> public
>   virtual string GetName() { return "Server::Interface1"; }
> };

> The method Server::GetName is executed whether invoked through
> Interface1 or Interface2. What I'd like to do, is to in the server
> class specify which of the two methods I want to override. E.g. by the
> following syntax:


> class Server: public Interface1, Interface2
> {
> public
>   virtual string Interface1::GetName() {return "Server::Interface1";}
>   virtual string Interface2::GetName();
> };

> string Server::Interface2::GetName() {return "Server::Interface2";}

There are two different issues that arise here, but you are only dealing
with one.  The other is, what should happen when I call GetName()
directly from a Server?

The way to deal with both of these problems at once is to not implement
GetName() in Server at all, but to use two intermediate classes:

class ServerInterface1 : public Interface1
{
   public:
      virtual string GetName() { return GetNameInterface1(); }
      virtual string GetNameInterface1() = 0;
};

class ServerInterface2 : public Interface2
{
   public:
      virtual string GetName() { return GetNameInterface2(); }
      virtual string GetNameInterface2() = 0;
};

class Server : public ServerInterface1, public ServerInterface2
{
   public:
      virtual string GetNameInterface1() { return "Server::Interface1"; }
      virtual string GetNameInterface2() { return "Server::Interface2"; }
};


Now, if a user calls GetName() through either Interface1 or Interface1,
he will get the correct answer.  If the user calls GetName() through
Server, he will get a compilation error (ambiguous).

For a better explanation of all this, check out Rule 43 in Scott Meyer's
book _Effective_C++_.  If you don't own the book already, you should.

> Is it, in the current state of the C++ 'standard', possible to specify
> this- which of the same named methods from different base classes to
> override? If not, should it be possible?

It is not in the standard, nor will it ever be.  Since there is an easy
way to do this directly, there is no reason to add it.

--
Colin
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]