Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #8139 > unrolled thread
| Started by | TP <Tribulations@Paralleles.invalid> |
|---|---|
| First post | 2011-07-24 17:40 +0200 |
| Last post | 2011-07-26 08:35 +0200 |
| Articles | 20 on this page of 30 — 14 participants |
Back to article view | Back to comp.lang.c++
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 →
| From | TP <Tribulations@Paralleles.invalid> |
|---|---|
| Date | 2011-07-24 17:40 +0200 |
| Subject | duct 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]
| From | Alain Ketterlin <alain@dpt-info.u-strasbg.fr> |
|---|---|
| Date | 2011-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]
| From | Marcel Müller <news.5.maazl@spamgourmet.org> |
|---|---|
| Date | 2011-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]
| From | Alain Ketterlin <alain@dpt-info.u-strasbg.fr> |
|---|---|
| Date | 2011-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]
| From | Goran <goran.pusic@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Nobody <nobody@nowhere.com> |
|---|---|
| Date | 2011-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]
| From | TP <Tribulations@Paralleles.invalid> |
|---|---|
| Date | 2011-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]
| From | Alain Ketterlin <alain@dpt-info.u-strasbg.fr> |
|---|---|
| Date | 2011-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]
| From | TP <Tribulations@Paralleles.invalid> |
|---|---|
| Date | 2011-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]
| From | Dombo <dombo@disposable.invalid> |
|---|---|
| Date | 2011-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]
| From | Alain Ketterlin <alain@dpt-info.u-strasbg.fr> |
|---|---|
| Date | 2011-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]
| From | Nobody <nobody@nowhere.com> |
|---|---|
| Date | 2011-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]
| From | TP <Tribulations@Paralleles.invalid> |
|---|---|
| Date | 2011-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]
| From | Stuart Redmann <DerTopper@web.de> |
|---|---|
| Date | 2011-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]
| From | TP <Tribulations@Paralleles.invalid> |
|---|---|
| Date | 2011-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]
| From | Paavo Helde <myfirstname@osa.pri.ee> |
|---|---|
| Date | 2011-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]
| From | Goran <goran.pusic@gmail.com> |
|---|---|
| Date | 2011-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]
| From | James Kanze <james.kanze@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Dombo <dombo@disposable.invalid> |
|---|---|
| Date | 2011-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]
| From | Dombo <dombo@disposable.invalid> |
|---|---|
| Date | 2011-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