Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #8139 > unrolled thread

duct typing and interface in C++

Started byTP <Tribulations@Paralleles.invalid>
First post2011-07-24 17:40 +0200
Last post2011-07-26 08:35 +0200
Articles 20 on this page of 30 — 14 participants

Back to article view | Back to comp.lang.c++


Contents

  duct typing and interface in C++ TP <Tribulations@Paralleles.invalid> - 2011-07-24 17:40 +0200
    Re: duct typing and interface in C++ Alain Ketterlin <alain@dpt-info.u-strasbg.fr> - 2011-07-24 18:11 +0200
      Re: duct typing and interface in C++ Marcel Müller <news.5.maazl@spamgourmet.org> - 2011-07-25 00:03 +0200
        Re: duct typing and interface in C++ Alain Ketterlin <alain@dpt-info.u-strasbg.fr> - 2011-07-25 10:11 +0200
        Re: duct typing and interface in C++ Goran <goran.pusic@gmail.com> - 2011-07-25 04:18 -0700
    Re: duct typing and interface in C++ Nobody <nobody@nowhere.com> - 2011-07-24 17:39 +0100
      Re: duct typing and interface in C++ TP <Tribulations@Paralleles.invalid> - 2011-07-24 19:55 +0200
        Re: duct typing and interface in C++ Alain Ketterlin <alain@dpt-info.u-strasbg.fr> - 2011-07-24 20:11 +0200
          Re: duct typing and interface in C++ TP <Tribulations@Paralleles.invalid> - 2011-07-24 20:23 +0200
            Re: duct typing and interface in C++ Dombo <dombo@disposable.invalid> - 2011-07-24 20:45 +0200
            Re: duct typing and interface in C++ Alain Ketterlin <alain@dpt-info.u-strasbg.fr> - 2011-07-24 21:10 +0200
            Re: duct typing and interface in C++ Nobody <nobody@nowhere.com> - 2011-07-24 21:21 +0100
              Re: duct typing and interface in C++ TP <Tribulations@Paralleles.invalid> - 2011-07-24 23:50 +0200
                Re: duct typing and interface in C++ Stuart Redmann <DerTopper@web.de> - 2011-07-24 23:33 -0700
                  Re: duct typing and interface in C++ TP <Tribulations@Paralleles.invalid> - 2011-07-25 23:00 +0200
                Re: duct typing and interface in C++ Paavo Helde <myfirstname@osa.pri.ee> - 2011-07-25 01:35 -0500
                Re: duct typing and interface in C++ Goran <goran.pusic@gmail.com> - 2011-07-25 04:10 -0700
            Re: duct typing and interface in C++ James Kanze <james.kanze@gmail.com> - 2011-07-30 11:51 -0700
        Re: duct typing and interface in C++ Dombo <dombo@disposable.invalid> - 2011-07-24 20:21 +0200
          Re: duct typing and interface in C++ Dombo <dombo@disposable.invalid> - 2011-07-24 20:26 +0200
    Re: duct typing and interface in C++ Dombo <dombo@disposable.invalid> - 2011-07-24 18:36 +0200
      Re: duct typing and interface in C++ BGB <cr88192@hotmail.com> - 2011-07-24 10:02 -0700
    Re: duct typing and interface in C++ BGB <cr88192@hotmail.com> - 2011-07-24 09:45 -0700
      Re: duct typing and interface in C++ TP <Tribulations@Paralleles.invalid> - 2011-07-24 20:15 +0200
        Re: duct typing and interface in C++ BGB <cr88192@hotmail.com> - 2011-07-24 14:06 -0700
    Re: duct typing and interface in C++ Thomas Boell <tboell@domain.invalid> - 2011-07-25 02:05 +0200
    Re: duct typing and interface in C++ Qi <no@no.no> - 2011-07-25 09:54 +0800
    Re: duct typing and interface in C++ Werner Erasmus <werasm@gmail.com> - 2011-07-25 23:36 +0200
      Re: duct typing and interface in C++ Leigh Johnston <leigh@i42.co.uk> - 2011-07-25 23:22 +0100
        Re: duct typing and interface in C++ Werner Erasmus <werasm@gmail.com> - 2011-07-26 08:35 +0200

Page 1 of 2  [1] 2  Next page →


#8139 — duct typing and interface in C++

FromTP <Tribulations@Paralleles.invalid>
Date2011-07-24 17:40 +0200
Subjectduct typing and interface in C++
Message-ID<ivqtf8-ke1.ln1@rama.nodalpoint.universe>
Hello,

I convert a Python/Qt program (PyQt) in C++/Qt.
The programmer has used the duck typing of Python, thus I would like to have 
duck typing in C++, in fact exactly what is described in the "best answer" 
at the following address:

http://stackoverflow.com/questions/289176/how-is-duck-typing-different-from-
the-old-variant-type-and-or-interfaces

(the "best answer" is the second post of the page, the one with a green 
sign).

Is it possible in C++?

Thanks in advance,

TP

[toc] | [next] | [standalone]


#8140

FromAlain Ketterlin <alain@dpt-info.u-strasbg.fr>
Date2011-07-24 18:11 +0200
Message-ID<8762mrzmjj.fsf@dpt-info.u-strasbg.fr>
In reply to#8139
TP <Tribulations@Paralleles.invalid> writes:

> I convert a Python/Qt program (PyQt) in C++/Qt.
> The programmer has used the duck typing of Python, thus I would like to have 
> duck typing in C++, in fact exactly what is described in the "best answer" 
> at the following address:
>
> http://stackoverflow.com/questions/289176/how-is-duck-typing-different-from-
> the-old-variant-type-and-or-interfaces
>
> (the "best answer" is the second post of the page, the one with a green 
> sign).
>
> Is it possible in C++?

Come on, duck typing is a funny name for "no static typing, cross
fingers at runtime". There is no such thing in C++, which is a
statically typed, object-oriented language. This means that a call like
o.quack() in C++ will never crash at runtime with a message like "no
such method". You don't even have to write dozens of tests verify that,
it's guaranteed by the compiler.

Read about "interfaces", or "pure virtual classes".

-- Alain.

[toc] | [prev] | [next] | [standalone]


#8158

FromMarcel Müller <news.5.maazl@spamgourmet.org>
Date2011-07-25 00:03 +0200
Message-ID<4e2c969a$0$6576$9b4e6d93@newsspool3.arcor-online.net>
In reply to#8140
On 24.07.11 18.11, Alain Ketterlin wrote:
> Come on, duck typing is a funny name for "no static typing, cross
> fingers at runtime". There is no such thing in C++, which is a
> statically typed, object-oriented language. This means that a call like
> o.quack() in C++ will never crash at runtime with a message like "no
> such method".

Well that is not true in all cases. E.g. the following code will call a 
non-existent function and abort at runtime.

#include <stdio.h>

class A
{public:
   virtual void foo() = 0;
   A() { bar(); }
  private:
   void bar() { foo(); }
};

class B : public A
{public:
   virtual void foo() { puts("B::foo"); }
};

int main()
{ B b;
   return 0;
}


Marcel

[toc] | [prev] | [next] | [standalone]


#8171

FromAlain Ketterlin <alain@dpt-info.u-strasbg.fr>
Date2011-07-25 10:11 +0200
Message-ID<87pqkyye3p.fsf@dpt-info.u-strasbg.fr>
In reply to#8158
Marcel Müller <news.5.maazl@spamgourmet.org> writes:

> On 24.07.11 18.11, Alain Ketterlin wrote:
>> Come on, duck typing is a funny name for "no static typing, cross
>> fingers at runtime". There is no such thing in C++, which is a
>> statically typed, object-oriented language. This means that a call like
>> o.quack() in C++ will never crash at runtime with a message like "no
>> such method".
>
> Well that is not true in all cases. E.g. the following code will call
> a non-existent function and abort at runtime.

[snip example with a call to a pure virtual in a ctor]

This explicitly prohibited by the language definition, so you get what
you deserve (a bit like the OP casting from one type to the other). BTW,
the message at runtime is not "no such function", it is "pure virtual
function called". Note also that if you give a body to the virtual
function in the base class, the call will succeed and execute that body.

-- Alain.

[toc] | [prev] | [next] | [standalone]


#8188

FromGoran <goran.pusic@gmail.com>
Date2011-07-25 04:18 -0700
Message-ID<6438397c-1e2a-4072-968f-077379c1a873@a4g2000yqg.googlegroups.com>
In reply to#8158
On Jul 25, 12:03 am, Marcel Müller <news.5.ma...@spamgourmet.org>
wrote:
> On 24.07.11 18.11, Alain Ketterlin wrote:
>
> > Come on, duck typing is a funny name for "no static typing, cross
> > fingers at runtime". There is no such thing in C++, which is a
> > statically typed, object-oriented language. This means that a call like
> > o.quack() in C++ will never crash at runtime with a message like "no
> > such method".
>
> Well that is not true in all cases. E.g. the following code will call a
> non-existent function and abort at runtime.
>
> #include <stdio.h>
>
> class A
> {public:
>    virtual void foo() = 0;
>    A() { bar(); }
>   private:
>    void bar() { foo(); }
>
> };
>
> class B : public A
> {public:
>    virtual void foo() { puts("B::foo"); }
>
> };
>
> int main()
> { B b;
>    return 0;
>
> }

Hmmm... Original post says "This means that a call like o.quack() in C+
+ will never crash at runtime". It looks implied that there's an
object instance to call a method on (o.quack()). You don't really have
that "o" ;-).

Goran.

[toc] | [prev] | [next] | [standalone]


#8141

FromNobody <nobody@nowhere.com>
Date2011-07-24 17:39 +0100
Message-ID<pan.2011.07.24.16.39.52.289000@nowhere.com>
In reply to#8139
On Sun, 24 Jul 2011 17:40:02 +0200, TP wrote:

> I convert a Python/Qt program (PyQt) in C++/Qt. The programmer has used
> the duck typing of Python, thus I would like to have duck typing in C++,

> Is it possible in C++?

Duck typing is just interfaces, which are just classes with no member
variables and only pure virtual methods.

[toc] | [prev] | [next] | [standalone]


#8147

FromTP <Tribulations@Paralleles.invalid>
Date2011-07-24 19:55 +0200
Message-ID<bu2uf8-lkq.ln1@rama.nodalpoint.universe>
In reply to#8141
Nobody wrote:

> On Sun, 24 Jul 2011 17:40:02 +0200, TP wrote:
> 
>> I convert a Python/Qt program (PyQt) in C++/Qt. The programmer has used
>> the duck typing of Python, thus I would like to have duck typing in C++,
> 
>> Is it possible in C++?
> 
> Duck typing is just interfaces, which are just classes with no member
> variables and only pure virtual methods.

I have tried to convert the example of the webpage I mentioned:

#include <iostream>

class InterfaceDuck
{
    public:
        virtual void Quack() = 0;
};

class Daffy
{
    public:
        void Quack()
        {
            std::cout << "coin coin" << std::endl;
        }
};

int main( void )
{
    InterfaceDuck * d = new Daffy;
    d->Quack();

    delete d;

    return 0;
}

At the compilation, I obtain:
$ g++ -Wall test.cpp
test.cpp: In function ?int main()?:
test.cpp:21:21: error: cannot convert ?Daffy*? to ?InterfaceDuck*? in 
initialization

Now, if I replace the line:
    InterfaceDuck * d = new Daffy;
by:
    InterfaceDuck * d = (InterfaceDuck *) new Daffy;

It compiles without warning, but it segfaults at the execution.
So, what is the correct way of doing things with pure virtual classes?

Thanks,

TP

[toc] | [prev] | [next] | [standalone]


#8148

FromAlain Ketterlin <alain@dpt-info.u-strasbg.fr>
Date2011-07-24 20:11 +0200
Message-ID<871uxfzgzp.fsf@dpt-info.u-strasbg.fr>
In reply to#8147
TP <Tribulations@Paralleles.invalid> writes:

> class InterfaceDuck
> {
>     public:
>         virtual void Quack() = 0;
> };
>
> class Daffy

class Daffy : public InterfaceDuck

> {
>     public:
>         void Quack()
>         {
>             std::cout << "coin coin" << std::endl;
>         }
> };
[...]
> $ g++ -Wall test.cpp
> test.cpp: In function ?int main()?:
> test.cpp:21:21: error: cannot convert ?Daffy*? to ?InterfaceDuck*? in 
> initialization

Inheritance must be explicit for the types to be compatible.

-- Alain.

[toc] | [prev] | [next] | [standalone]


#8151

FromTP <Tribulations@Paralleles.invalid>
Date2011-07-24 20:23 +0200
Message-ID<0j4uf8-a9j.ln1@rama.nodalpoint.universe>
In reply to#8148
Alain Ketterlin wrote:

> class Daffy : public InterfaceDuck

> Inheritance must be explicit for the types to be compatible.

In fact, I would like to have duck typing exactly as in Python: in Python 
there is no need to have an inheritance relation between the interface and 
the class Daffy.
In my previous post, I pointed to an example with no such inheritance 
relation:

http://stackoverflow.com/questions/289176/how-is-duck-typing-different-from-
the-old-variant-type-and-or-interfaces

I would like to have a construction where the following affectation is 
possible:

InterfaceDuck * d = new Daffy;

without inheritance relation between InterfaceDuck and Daffy.
The fact that Daffy has a method Quack() as InterfaceDuck should be enough 
to allow that.

But perhaps there is no means to do that in C++?

TP

[toc] | [prev] | [next] | [standalone]


#8153

FromDombo <dombo@disposable.invalid>
Date2011-07-24 20:45 +0200
Message-ID<4e2c6837$0$30733$5fc3050@news.tiscali.nl>
In reply to#8151
Op 24-Jul-11 20:23, TP schreef:
> Alain Ketterlin wrote:
>
>> class Daffy : public InterfaceDuck
>
>> Inheritance must be explicit for the types to be compatible.
>
> In fact, I would like to have duck typing exactly as in Python: in Python
> there is no need to have an inheritance relation between the interface and
> the class Daffy.
> In my previous post, I pointed to an example with no such inheritance
> relation:
>
> http://stackoverflow.com/questions/289176/how-is-duck-typing-different-from-
> the-old-variant-type-and-or-interfaces
>
> I would like to have a construction where the following affectation is
> possible:
>
> InterfaceDuck * d = new Daffy;
>
> without inheritance relation between InterfaceDuck and Daffy.

That is not possible in C++. Casting won't work be cause is Daffy isn't 
a InterfaceDuck. In this case casting would be lying to your compiler, 
and the compiler will have its revenge on you sooner or later for doing 
that.

> The fact that Daffy has a method Quack() as InterfaceDuck should be enough
> to allow that.

Nope, C++ doesn't work that way. You must explicitly derive from 
InterfaceDuck so the compiler knows that it is your intention that Daffy 
can be used wherever InterfaceDuck is expected (i.e there is a is-a 
relationship between Daffy and InterfaceDuck). That two classes merely 
have a method that happens to have the same name is not good enough for 
C++.

> But perhaps there is no means to do that in C++?

Like I said before with templates may be able get a sort of duck typing 
in C++.

However it will never be the same as in Python. The fundamental 
difference between Python and C++ is that Python is a dynamically typed 
language where as C++ is statically typed. This requires a different 
approach and I doubt trying to write a program the Python way in C++ is 
a good idea.

[toc] | [prev] | [next] | [standalone]


#8154

FromAlain Ketterlin <alain@dpt-info.u-strasbg.fr>
Date2011-07-24 21:10 +0200
Message-ID<87wrf7xznx.fsf@dpt-info.u-strasbg.fr>
In reply to#8151
TP <Tribulations@Paralleles.invalid> writes:

> Alain Ketterlin wrote:
>
>> class Daffy : public InterfaceDuck
>
>> Inheritance must be explicit for the types to be compatible.
>
> In fact, I would like to have duck typing exactly as in Python:

You can't.

> in Python there is no need to have an inheritance relation between the
> interface and the class Daffy. In my previous post, I pointed to an
> example with no such inheritance relation:
>
> http://stackoverflow.com/questions/289176/how-is-duck-typing-different-from-
> the-old-variant-type-and-or-interfaces
>
> I would like to have a construction where the following affectation is 
> possible:
>
> InterfaceDuck * d = new Daffy;

No way, unless InterfaceDuck and Daffy are linked by inheritance.

If you then call d->quack(), the compiler has to make sure *at compile
time* there actually is a method quack to call on d (even though it may
not be able to decide exactly which one will be called).

This is called static typing, a thing python doesn't do.

Typing is a basic programming notion, I suggest you read
http://en.wikipedia.org/wiki/Type_system

-- Alain.

[toc] | [prev] | [next] | [standalone]


#8155

FromNobody <nobody@nowhere.com>
Date2011-07-24 21:21 +0100
Message-ID<pan.2011.07.24.20.21.55.211000@nowhere.com>
In reply to#8151
On Sun, 24 Jul 2011 20:23:59 +0200, TP wrote:

> In fact, I would like to have duck typing exactly as in Python:

Then use Python.

> in Python 
> there is no need to have an inheritance relation between the interface and 
> the class Daffy.

That's because Python is a dynamically-typed language, where method
look-up is done at run time.

> In my previous post, I pointed to an example with no such inheritance 
> relation:
> 
> http://stackoverflow.com/questions/289176/how-is-duck-typing-different-from-
> the-old-variant-type-and-or-interfaces

Note that the code given there isn't valid C++.

> I would like to have a construction where the following affectation is 
> possible:
> 
> InterfaceDuck * d = new Daffy;
> 
> without inheritance relation between InterfaceDuck and Daffy.
> The fact that Daffy has a method Quack() as InterfaceDuck should be enough 
> to allow that.
> 
> But perhaps there is no means to do that in C++?

Well, not unless you consider using C++ to write a dynamically-typed
language such as Python to be a solution.

If, for some reason, you can't make specific classes derive from
InterfaceDuck, you can use a template to create a wrapper or proxy for
such classes, e.g.:

template <class T>
class ProxyDuck : public InterfaceDuck {
	T& ref;
	ProxyDuck(T& ref) : ref(ref) {}
	void quack() { ref.quack(); }
};

[toc] | [prev] | [next] | [standalone]


#8157

FromTP <Tribulations@Paralleles.invalid>
Date2011-07-24 23:50 +0200
Message-ID<nlguf8-nv9.ln1@rama.nodalpoint.universe>
In reply to#8155
Nobody wrote:

> If, for some reason, you can't make specific classes derive from
> InterfaceDuck, you can use a template to create a wrapper or proxy for
> such classes, e.g.:
> 
> template <class T>
> class ProxyDuck : public InterfaceDuck {
> T& ref;
> ProxyDuck(T& ref) : ref(ref) {}
> void quack() { ref.quack(); }
> };

Thanks all for your answers.

Template/proxy may be the better solution in my case (to avoid to be 
compelled to do multiple inheritance in my real case).

But I have to go deeper in templates, which are still complicated to read 
for me.

If I have the two solutions: (i) templating a class, or (ii) using multiple 
inheritance, what is the best solution?

NOTE: if some (all?) of you understand Qt, this is my precise problem (Qt is 
not the subject of this group, that's why I explain that only now): I define 
a QWidget w1, which can include a QWidget w2 that must implement some 
methods to be used (say: setText, readText). But if w2 is not given, w1 
creates a default w2. w2 is a member of w1, in Python no type is needed for 
w2, it must only provide setText and readText. But in C++, I must give a 
type to w2 in the definition of w1. I could declare w1 as a template for w2. 
But I could also make mandatory to have w2 to derive from an interface 
(abstract class) containing setText and readText as pure virtual method; in 
this case, as w2 will already derive from some Qt class, we have multiple 
inheritance.
Do you understand my problem?

[toc] | [prev] | [next] | [standalone]


#8167

FromStuart Redmann <DerTopper@web.de>
Date2011-07-24 23:33 -0700
Message-ID<018f03ae-2597-448f-893c-1cb45659323c@gv8g2000vbb.googlegroups.com>
In reply to#8157
On 24 Jul., TP wrote:
> NOTE: if some (all?) of you understand Qt, this is my precise problem (Qt is
> not the subject of this group, that's why I explain that only now): I define
> a QWidget w1, which can include a QWidget w2 that must implement some
> methods to be used (say: setText, readText). But if w2 is not given, w1
> creates a default w2. w2 is a member of w1, in Python no type is needed for
> w2, it must only provide setText and readText. But in C++, I must give a
> type to w2 in the definition of w1. I could declare w1 as a template for w2.
> But I could also make mandatory to have w2 to derive from an interface
> (abstract class) containing setText and readText as pure virtual method; in
> this case, as w2 will already derive from some Qt class, we have multiple
> inheritance.
> Do you understand my problem?

I think the template based approach should do:

template<class t_ClassTypeOfW2 = DefaultClassForW2>
class MyWidget : public QWidget
{
private:
  t_ClassTypeOfW2 w2;

  void foo ()
  {
    w2.SetText ("foo");
  }
};

Now you can put any class into t_ClassTypeOfW2 as long as it has a
SetText method (no interfaces needed). However, if you would like to
determine the type of w2 at run-time (or change it), you'll have to
resort to the interface based solution.

Regards,
Stuart

[toc] | [prev] | [next] | [standalone]


#8215

FromTP <Tribulations@Paralleles.invalid>
Date2011-07-25 23:00 +0200
Message-ID<k321g8-g1p.ln1@rama.nodalpoint.universe>
In reply to#8167
Stuart Redmann wrote:

> I think the template based approach should do:
> 
> template<class t_ClassTypeOfW2 = DefaultClassForW2>
> class MyWidget : public QWidget
> {
> private:
>   t_ClassTypeOfW2 w2;
> 
>   void foo ()
>   {
>     w2.SetText ("foo");
>   }
> };
> 
> Now you can put any class into t_ClassTypeOfW2 as long as it has a
> SetText method (no interfaces needed). However, if you would like to
> determine the type of w2 at run-time (or change it), you'll have to
> resort to the interface based solution.
> 
> Regards,
> Stuart

Thanks for your answer. At first sight templating seems to me easier than 
multiple inheritance (I have read about multiple inheritance this evening, 
there is some subtleties, sometimes).
Below is my solution, in the case of the "duck example" of this post, 
inspired from your answer and the one of Nobody.
I have to read further concerning what a proxy is, because below I use this 
denomination without really mastering it!
I fact, I realize only now that what I needed is *static* duck typing. So 
templating (parametric polymorphism) is the easier solution, it seems.

1/ The version with interface:
==============================

#include <iostream>

class InterfaceDuck
{
public:
    virtual void Quack() = 0;
};

class Daffy
{
public:
    void Quack()
    {
        std::cout << "coin coin, I'm Daffy" << std::endl;
    }
};

class Donald
{
public:
    void Quack()
    {
        std::cout << "coin coin, I'm Donald" << std::endl;
    }
};

template <class T>
class ProxyDuck : public InterfaceDuck
{
public:
    T * ref;
    ProxyDuck(T * ref) : ref(ref) {}
    void Quack() { ref->Quack(); }
};

int main( void )
{
    Daffy * dada = new Daffy;
    Donald * dodo = new Donald;
    ProxyDuck<Daffy> * d = new ProxyDuck<Daffy> ( dada );
    ProxyDuck<Donald> * e = new ProxyDuck<Donald> ( dodo );

    std::cout << "Daffy is going to quack" << std::endl;
    d->Quack();
    std::cout << "Donald is going to quack" << std::endl;
    e->Quack();

    delete d;
    delete e;

    return 0;
}

2/ The version without interface:
=================================

#include <iostream>

class Daffy
{
public:
    void Quack()
    {
        std::cout << "coin coin, I'm Daffy" << std::endl;
    }
};

class Donald
{
public:
    void Quack()
    {
        std::cout << "coin coin, I'm Donald" << std::endl;
    }
};

template <class T>
class ProxyDuck
{
public:
    T * ref;
    ProxyDuck(T * ref) : ref(ref) {}
    void Quack() { ref->Quack(); }
};

int main( void )
{
    Daffy * dada = new Daffy;
    Donald * dodo = new Donald;
    ProxyDuck<Daffy> * d = new ProxyDuck<Daffy> ( dada );
    ProxyDuck<Donald> * e = new ProxyDuck<Donald> ( dodo );

    std::cout << "Daffy is going to quack" << std::endl;
    d->Quack();
    std::cout << "Donald is going to quack" << std::endl;
    e->Quack();

    delete d;
    delete e;

    return 0;
}


[toc] | [prev] | [next] | [standalone]


#8168

FromPaavo Helde <myfirstname@osa.pri.ee>
Date2011-07-25 01:35 -0500
Message-ID<Xns9F2D61969B70myfirstnameosapriee@216.196.109.131>
In reply to#8157
TP <Tribulations@Paralleles.invalid> wrote in
news:nlguf8-nv9.ln1@rama.nodalpoint.universe: 

> Nobody wrote:
> 
>> If, for some reason, you can't make specific classes derive from
>> InterfaceDuck, you can use a template to create a wrapper or proxy
>> for such classes, e.g.:
>> 
>> template <class T>
>> class ProxyDuck : public InterfaceDuck {
>> T& ref;
>> ProxyDuck(T& ref) : ref(ref) {}
>> void quack() { ref.quack(); }
>> };
> 
> Thanks all for your answers.
> 
> Template/proxy may be the better solution in my case (to avoid to be 
> compelled to do multiple inheritance in my real case).

Template+proxy are probably more complicated than multiple inheritance, 
so it would not make sense to (ab)use them in this way just to avoid MI. 
MI works fine in C++, and one can use dynamic_cast for "discovering" the 
interfaces the object supports. Maybe you need virtual inheritance as 
well.

> 
> But I have to go deeper in templates, which are still complicated to
> read for me.
> 
> If I have the two solutions: (i) templating a class, or (ii) using
> multiple inheritance, what is the best solution?

Templates are a purely compile-time thing, so anything which has to be 
decided on run-time, cannot be solved by any template trickery. And vice 
versa, dynamic_cast is (almost) purely a run-time thing.

> 
> NOTE: if some (all?) of you understand Qt, this is my precise problem
> (Qt is not the subject of this group, that's why I explain that only
> now): I define a QWidget w1, which can include a QWidget w2 that must
> implement some methods to be used (say: setText, readText). But if w2
> is not given, w1 creates a default w2. w2 is a member of w1, in Python
> no type is needed for w2, it must only provide setText and readText.
> But in C++, I must give a type to w2 in the definition of w1. I could
> declare w1 as a template for w2. But I could also make mandatory to
> have w2 to derive from an interface (abstract class) containing
> setText and readText as pure virtual method; in this case, as w2 will
> already derive from some Qt class, we have multiple inheritance.
> Do you understand my problem?

If the decision whether to create default w2 or not is made at run-time 
only, then one cannot solve this by templates only. You will need objects 
sharing the same interface, which in C++ means that you must have a 
common base class with virtual functions. 

Multiple inheritance seems the best fit here, why are you afraid of it? I 
have done the similar thing with the MFC framework and in general it 
works well. For example, if you have (a pointer to) a Qt class and you 
need a pointer to the w2 interface (or vice versa), you just apply the 
dynamic_cast operation to obtain it. This would be semantically 
equivalent to the run-time method lookup what Python is performing all 
over the place.

A word of caution: with the MFC framework one has to be careful and 
derive from the MFC class first as MFC uses other casts instead of 
dynamic_cast, which would do the wrong thing otherwise. I have not used 
Qt so I don't know if such a thing is needed with Qt as well or not.


hth
Paavo

[toc] | [prev] | [next] | [standalone]


#8187

FromGoran <goran.pusic@gmail.com>
Date2011-07-25 04:10 -0700
Message-ID<489466dd-d9e0-4108-b4d5-65b1002fbfe3@w27g2000yqk.googlegroups.com>
In reply to#8157
On Jul 24, 11:50 pm, TP <Tribulati...@Paralleles.invalid> wrote:
> NOTE: if some (all?) of you understand Qt, this is my precise problem (Qt is
> not the subject of this group, that's why I explain that only now): I define
> a QWidget w1, which can include a QWidget w2 that must implement some
> methods to be used (say: setText, readText). But if w2 is not given, w1
> creates a default w2. w2 is a member of w1, in Python no type is needed for
> w2, it must only provide setText and readText. But in C++, I must give a
> type to w2 in the definition of w1. I could declare w1 as a template for w2.
> But I could also make mandatory to have w2 to derive from an interface
> (abstract class) containing setText and readText as pure virtual method; in
> this case, as w2 will already derive from some Qt class, we have multiple
> inheritance.
> Do you understand my problem?

This situation is not specific to Qt. If I were you, I'd do the usual
(or so I think) interface approach:

interface.h
struct IHasText
{
  virtual void setText(const QString&) = 0;
  virtual QString getText() = 0;
};

factory.h
extern IHasText* createHasText(params);

widget2.h
class Widget2 : public QSomething, IHasText
{
 // Implement get/setText here
};

Widget1.h
struct IHasText;
class Widget1
{
  IHasText* textProvider_;
};

widget1.cpp
#include "widget.h"
#include "interface.h"
#include "factory.h"
// Implementation of Widget1. E.g.
Widget1::Widget1() : textProvider_(NULL)
{
  textProvider_ = createTextProvider(params);
}

(Or something to that extent).

Goran.

[toc] | [prev] | [next] | [standalone]


#8338

FromJames Kanze <james.kanze@gmail.com>
Date2011-07-30 11:51 -0700
Message-ID<08bc7d5d-8ed3-4353-824a-bff5184d5c34@d32g2000yqa.googlegroups.com>
In reply to#8151
On Jul 24, 7:23 pm, TP <Tribulati...@Paralleles.invalid> wrote:
> Alain Ketterlin wrote:
> > class Daffy : public InterfaceDuck
> > Inheritance must be explicit for the types to be compatible.

> In fact, I would like to have duck typing exactly as in
> Python: in Python there is no need to have an inheritance
> relation between the interface and the class Daffy.  In my
> previous post, I pointed to an example with no such
> inheritance relation:

> http://stackoverflow.com/questions/289176/how-is-duck-typing-differen...
> the-old-variant-type-and-or-interfaces

> I would like to have a construction where the following
> affectation is possible:

> InterfaceDuck * d = new Daffy;

> without inheritance relation between InterfaceDuck and Daffy.
> The fact that Daffy has a method Quack() as InterfaceDuck
> should be enough to allow that.

> But perhaps there is no means to do that in C++?

There isn't.  Python and C++ are designed to fulfill different
roles.  Duck typing would make C++ inappropriate for many of the
roles it now fills.  Duck typing means, for example, only
finding out about errors at runtime.  No big deal in a small
program, written in a language without a compiler, in an
interactive development environment, and where robustness isn't
paramount.  Not having duck typing means having to go back and
add the proper base classes every time you extend a class to
support a new protocol.  Not appropriate in an experimental and
highly dynamic environment, and overkill (and a lot of extra
work) in very small, frequently changing programs.

--
James Kanze

[toc] | [prev] | [next] | [standalone]


#8150

FromDombo <dombo@disposable.invalid>
Date2011-07-24 20:21 +0200
Message-ID<4e2c62b4$0$30705$5fc3050@news.tiscali.nl>
In reply to#8147
Op 24-Jul-11 19:55, TP schreef:
> Nobody wrote:
>
>> On Sun, 24 Jul 2011 17:40:02 +0200, TP wrote:
>>
>>> I convert a Python/Qt program (PyQt) in C++/Qt. The programmer has used
>>> the duck typing of Python, thus I would like to have duck typing in C++,
>>
>>> Is it possible in C++?
>>
>> Duck typing is just interfaces, which are just classes with no member
>> variables and only pure virtual methods.
>
> I have tried to convert the example of the webpage I mentioned:
>
> #include<iostream>
>
> class InterfaceDuck
> {
>      public:
>          virtual void Quack() = 0;
> };
>
> class Daffy
> {
>      public:
>          void Quack()
>          {
>              std::cout<<  "coin coin"<<  std::endl;
>          }
> };
>
> int main( void )
> {
>      InterfaceDuck * d = new Daffy;
>      d->Quack();
>
>      delete d;
>
>      return 0;
> }
>
> At the compilation, I obtain:
> $ g++ -Wall test.cpp
> test.cpp: In function ?int main()?:
> test.cpp:21:21: error: cannot convert ?Daffy*? to ?InterfaceDuck*? in
> initialization
>
> Now, if I replace the line:
>      InterfaceDuck * d = new Daffy;
> by:
>      InterfaceDuck * d = (InterfaceDuck *) new Daffy;
>
> It compiles without warning, but it segfaults at the execution.
> So, what is the correct way of doing things with pure virtual classes?
>
> Thanks,

You will have to derive Daffy from InterfaceDuck. Of course that way it 
is no longer really duck typing, but that should be a goal in itself anyway.

If for some reason it is not practical to derive from a common base 
class you might consider using templates instead:

#include <iostream>

class Donald
{
public:
     void quack()
     {
         std::cout << "Donald: Oh, yeah?" << std::endl;
     }
};

class Daffy
{
public:
     void quack()
     {
         std::cout << "Daffy: Thatsssss dispicable!!!!" << std::endl;
     }
};


template<class T>
void foo(T& duck)
{
     duck.quack();
}


int main()
{
     Daffy daffy;
     foo(daffy);

     Donald donald;
     foo(donald);

     return 0;
}




[toc] | [prev] | [next] | [standalone]


#8152

FromDombo <dombo@disposable.invalid>
Date2011-07-24 20:26 +0200
Message-ID<4e2c63d6$0$30705$5fc3050@news.tiscali.nl>
In reply to#8150
Op 24-Jul-11 20:21, Dombo schreef:
> Op 24-Jul-11 19:55, TP schreef:
>> Nobody wrote:
>>
>>> On Sun, 24 Jul 2011 17:40:02 +0200, TP wrote:
>>>
>>>> I convert a Python/Qt program (PyQt) in C++/Qt. The programmer has used
>>>> the duck typing of Python, thus I would like to have duck typing in
>>>> C++,
>>>
>>>> Is it possible in C++?
>>>
>>> Duck typing is just interfaces, which are just classes with no member
>>> variables and only pure virtual methods.
>>
>> I have tried to convert the example of the webpage I mentioned:
>>
>> #include<iostream>
>>
>> class InterfaceDuck
>> {
>> public:
>> virtual void Quack() = 0;
>> };
>>
>> class Daffy
>> {
>> public:
>> void Quack()
>> {
>> std::cout<< "coin coin"<< std::endl;
>> }
>> };
>>
>> int main( void )
>> {
>> InterfaceDuck * d = new Daffy;
>> d->Quack();
>>
>> delete d;
>>
>> return 0;
>> }
>>
>> At the compilation, I obtain:
>> $ g++ -Wall test.cpp
>> test.cpp: In function ?int main()?:
>> test.cpp:21:21: error: cannot convert ?Daffy*? to ?InterfaceDuck*? in
>> initialization
>>
>> Now, if I replace the line:
>> InterfaceDuck * d = new Daffy;
>> by:
>> InterfaceDuck * d = (InterfaceDuck *) new Daffy;
>>
>> It compiles without warning, but it segfaults at the execution.
>> So, what is the correct way of doing things with pure virtual classes?
>>
>> Thanks,
>
> You will have to derive Daffy from InterfaceDuck. Of course that way it
> is no longer really duck typing, but that should be a goal in itself
> anyway.

Corrrection: that should *not* be a goal in itself anyway.

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.c++


csiph-web