derived class and virtual function

Discussion in 'C++' started by subramanian100in@yahoo.com, India, Aug 13, 2010.

  1. , India

    , India Guest

    In Stanley Lippman's 'C++ Primer Fourth Edition', in page 564, the
    following is mentioned:

    "A virtual function in the derived class can return a reference or
    pointer to a class that is PUBLICLY derived from the type returned by
    the base class function."

    I am unable to understand this sentence. Kindly explain it with
    program sample.

    Thanks
    V.Subramanian
     
    , India, Aug 13, 2010
    #1
    1. Advertising

  2. , India <>, on
    13/08/2010 01:29:13, wrote:

    > In Stanley Lippman's 'C++ Primer Fourth Edition', in page 564, the
    > following is mentioned:
    >
    > "A virtual function in the derived class can return a reference or
    > pointer to a class that is PUBLICLY derived from the type returned by
    > the base class function."
    >
    > I am unable to understand this sentence. Kindly explain it with
    > program sample.


    IIUIC, that means that if you have a function with signature "virtual
    Base* Clone() const;" in the base class, then the implementation of the
    same function in the derived class can be: "Base* Clone() const { return
    new Derived(*this); }" - just an example that assumes Derived is
    copy-constructible, of course.

    --
    FSC - http://userscripts.org/scripts/show/59948
    http://fscode.altervista.org - http://sardinias.com
     
    Francesco S. Carta, Aug 13, 2010
    #2
    1. Advertising

  3. On 8/13/2010 10:29 AM, , India wrote:
    > In Stanley Lippman's 'C++ Primer Fourth Edition', in page 564, the
    > following is mentioned:
    >
    > "A virtual function in the derived class can return a reference or
    > pointer to a class that is PUBLICLY derived from the type returned by
    > the base class function."
    >
    > I am unable to understand this sentence. Kindly explain it with
    > program sample.
    >
    > Thanks
    > V.Subramanian


    It allows you for example to write code like this (polymorphic copy)

    #include <iostream>
    class Foo
    {
    public:
    virtual Foo* createCopy(){ return new Foo(*this); }
    virtual void quack() { std::cout<<"I'm a foo"<<std::endl; }
    virtual ~Foo(){}
    };

    class Bar : public Foo
    {
    public:
    // notice that this createCopy returns a Bar* instead of Foo*
    // which is a "pointer to a class that is PUBLICLY derived"
    virtual Bar* createCopy(){ return new Bar(*this); }
    virtual void quack() { std::cout<<"I'm a bar"<<std::endl; }
    };

    int main() {
    Bar bar;
    Foo& br = bar;
    Foo* bp = br.createCopy();
    bp->quack();
    delete bp;
    }
     
    Stefan van Kessel, Aug 13, 2010
    #3
  4. Francesco S. Carta <>, on 13/08/2010 10:39:51, wrote:

    > , India <>, on
    > 13/08/2010 01:29:13, wrote:
    >
    >> In Stanley Lippman's 'C++ Primer Fourth Edition', in page 564, the
    >> following is mentioned:
    >>
    >> "A virtual function in the derived class can return a reference or
    >> pointer to a class that is PUBLICLY derived from the type returned by
    >> the base class function."
    >>
    >> I am unable to understand this sentence. Kindly explain it with
    >> program sample.

    >
    > IIUIC, that means that if you have a function with signature "virtual
    > Base* Clone() const;" in the base class, then the implementation of the
    > same function in the derived class can be: "Base* Clone() const { return
    > new Derived(*this); }" - just an example that assumes Derived is
    > copy-constructible, of course.


    There is either something wrong in that sentence, in my understanding
    or in my compiler - or my settings thereof - because it allows me to
    return a pointer to Derived where Base is private:

    //-------

    #include <iostream>

    using namespace std;

    class Base {
    public:
    Base(int data = 0) : data(data) {};
    Base(const Base& base) : data(base.data) {};
    virtual Base* Clone() const {
    cout << "cloning Base" << endl;
    return new Base(*this);
    }
    int Data() const {
    return data;
    }
    private:
    int data;
    };

    class Derived : private Base {
    public:
    Derived(int data = 0) : Base(data) {};
    Derived(const Derived& derived) : Base(derived) {};
    Base* Clone() const {
    cout << "cloning Derived" << endl;
    return new Derived(*this);
    }
    };

    int main() {

    // fails, of course
    // Base* pb = new Derived(42);

    Derived d(42);

    // calls Derived::Clone()
    Base* pb2 = d.Clone();

    // calls Derived::Clone()
    Base* pb3 = pb2->Clone();

    // prints 42
    cout << pb3->Data() << endl;
    }

    //-------


    --
    FSC - http://userscripts.org/scripts/show/59948
    http://fscode.altervista.org - http://sardinias.com
     
    Francesco S. Carta, Aug 13, 2010
    #4
  5. Stefan van Kessel <>, on 13/08/2010 10:51:30,
    wrote:

    > On 8/13/2010 10:29 AM, , India wrote:
    >> In Stanley Lippman's 'C++ Primer Fourth Edition', in page 564, the
    >> following is mentioned:
    >>
    >> "A virtual function in the derived class can return a reference or
    >> pointer to a class that is PUBLICLY derived from the type returned by
    >> the base class function."
    >>
    >> I am unable to understand this sentence. Kindly explain it with
    >> program sample.
    >>
    >> Thanks
    >> V.Subramanian

    >
    > It allows you for example to write code like this (polymorphic copy)
    >
    > #include <iostream>
    > class Foo
    > {
    > public:
    > virtual Foo* createCopy(){ return new Foo(*this); }
    > virtual void quack() { std::cout<<"I'm a foo"<<std::endl; }
    > virtual ~Foo(){}
    > };
    >
    > class Bar : public Foo
    > {
    > public:
    > // notice that this createCopy returns a Bar* instead of Foo*
    > // which is a "pointer to a class that is PUBLICLY derived"
    > virtual Bar* createCopy(){ return new Bar(*this); }
    > virtual void quack() { std::cout<<"I'm a bar"<<std::endl; }
    > };
    >
    > int main() {
    > Bar bar;
    > Foo& br = bar;
    > Foo* bp = br.createCopy();
    > bp->quack();
    > delete bp;
    > }


    Ah, this makes more sense than my example, but I've been able to make it
    work even declaring Bar::createCopy() as non-virtual, just for the records.

    --
    FSC - http://userscripts.org/scripts/show/59948
    http://fscode.altervista.org - http://sardinias.com
     
    Francesco S. Carta, Aug 13, 2010
    #5
  6. Stefan van Kessel on 13/08/2010 wrote:
    > > #include <iostream>
    > > class Foo
    > > {
    > > public:
    > > virtual Foo* createCopy(){ return new Foo(*this); }
    > > virtual void quack() { std::cout<<"I'm a foo"<<std::endl; }
    > > virtual ~Foo(){}
    > > };
    > >
    > > class Bar : public Foo
    > > {
    > > public:
    > > // notice that this createCopy returns a Bar* instead of Foo*
    > > // which is a "pointer to a class that is PUBLICLY derived"
    > > virtual Bar* createCopy(){ return new Bar(*this); }
    > > virtual void quack() { std::cout<<"I'm a bar"<<std::endl; }
    > > };
    > >
    > > int main() {
    > > Bar bar;
    > > Foo& br = bar;
    > > Foo* bp = br.createCopy();
    > > bp->quack();
    > > delete bp;
    > > }


    Francesco S. Carta wrote:
    > Ah, this makes more sense than my example, but I've been able to make it
    > work even declaring Bar::createCopy() as non-virtual, just for the records.


    A question pops up: How exactly did you manage to make Bar::createCopy
    non-virtual? AFAIK, C++ does not allow this.

    Regards,
    Stuart
     
    Stuart Redmann, Aug 13, 2010
    #6
  7. Stuart Redmann <>, on 13/08/2010 02:30:45, wrote:

    > Stefan van Kessel on 13/08/2010 wrote:
    >>> #include<iostream>
    >>> class Foo
    >>> {
    >>> public:
    >>> virtual Foo* createCopy(){ return new Foo(*this); }
    >>> virtual void quack() { std::cout<<"I'm a foo"<<std::endl; }
    >>> virtual ~Foo(){}
    >>> };
    >>>
    >>> class Bar : public Foo
    >>> {
    >>> public:
    >>> // notice that this createCopy returns a Bar* instead of Foo*
    >>> // which is a "pointer to a class that is PUBLICLY derived"
    >>> virtual Bar* createCopy(){ return new Bar(*this); }
    >>> virtual void quack() { std::cout<<"I'm a bar"<<std::endl; }
    >>> };
    >>>
    >>> int main() {
    >>> Bar bar;
    >>> Foo& br = bar;
    >>> Foo* bp = br.createCopy();
    >>> bp->quack();
    >>> delete bp;
    >>> }

    >
    > Francesco S. Carta wrote:
    >> Ah, this makes more sense than my example, but I've been able to make it
    >> work even declaring Bar::createCopy() as non-virtual, just for the records.

    >
    > A question pops up: How exactly did you manage to make Bar::createCopy
    > non-virtual? AFAIK, C++ does not allow this.


    I've just copied Stefan's code, pasted it into my editor, deleted the
    two "virtual" from createCopy() and quack() within class Bar and
    compiled it with MinGW 4.4.0.

    The output was: "I'm a bar".

    Notice that I wrote "declaring Bar::createCopy() as non-virtual", as far
    as I know I did not "make Bar::createCopy non-virtual" as you said.

    --
    FSC - http://userscripts.org/scripts/show/59948
    http://fscode.altervista.org - http://sardinias.com
     
    Francesco S. Carta, Aug 13, 2010
    #7
  8. , India

    Ian Collins Guest

    On 08/13/10 09:36 PM, Francesco S. Carta wrote:
    > Stuart Redmann <>, on 13/08/2010 02:30:45, wrote:
    >
    >> Stefan van Kessel on 13/08/2010 wrote:
    >>>> #include<iostream>
    >>>> class Foo
    >>>> {
    >>>> public:
    >>>> virtual Foo* createCopy(){ return new Foo(*this); }
    >>>> virtual void quack() { std::cout<<"I'm a foo"<<std::endl; }
    >>>> virtual ~Foo(){}
    >>>> };
    >>>>
    >>>> class Bar : public Foo
    >>>> {
    >>>> public:
    >>>> // notice that this createCopy returns a Bar* instead of Foo*
    >>>> // which is a "pointer to a class that is PUBLICLY derived"
    >>>> virtual Bar* createCopy(){ return new Bar(*this); }
    >>>> virtual void quack() { std::cout<<"I'm a bar"<<std::endl; }
    >>>> };
    >>>>
    >>>> int main() {
    >>>> Bar bar;
    >>>> Foo& br = bar;
    >>>> Foo* bp = br.createCopy();
    >>>> bp->quack();
    >>>> delete bp;
    >>>> }

    >>
    >> Francesco S. Carta wrote:
    >>> Ah, this makes more sense than my example, but I've been able to make it
    >>> work even declaring Bar::createCopy() as non-virtual, just for the
    >>> records.

    >>
    >> A question pops up: How exactly did you manage to make Bar::createCopy
    >> non-virtual? AFAIK, C++ does not allow this.

    >
    > I've just copied Stefan's code, pasted it into my editor, deleted the
    > two "virtual" from createCopy() and quack() within class Bar and
    > compiled it with MinGW 4.4.0.


    So the function are still virtual. The virtual keyword in the derived
    class is superfluous.

    --
    Ian Collins
     
    Ian Collins, Aug 13, 2010
    #8
  9. Ian Collins <>, on 13/08/2010 21:41:55, wrote:

    > On 08/13/10 09:36 PM, Francesco S. Carta wrote:
    >> Stuart Redmann <>, on 13/08/2010 02:30:45, wrote:
    >>
    >>> Stefan van Kessel on 13/08/2010 wrote:
    >>>>> #include<iostream>
    >>>>> class Foo
    >>>>> {
    >>>>> public:
    >>>>> virtual Foo* createCopy(){ return new Foo(*this); }
    >>>>> virtual void quack() { std::cout<<"I'm a foo"<<std::endl; }
    >>>>> virtual ~Foo(){}
    >>>>> };
    >>>>>
    >>>>> class Bar : public Foo
    >>>>> {
    >>>>> public:
    >>>>> // notice that this createCopy returns a Bar* instead of Foo*
    >>>>> // which is a "pointer to a class that is PUBLICLY derived"
    >>>>> virtual Bar* createCopy(){ return new Bar(*this); }
    >>>>> virtual void quack() { std::cout<<"I'm a bar"<<std::endl; }
    >>>>> };
    >>>>>
    >>>>> int main() {
    >>>>> Bar bar;
    >>>>> Foo& br = bar;
    >>>>> Foo* bp = br.createCopy();
    >>>>> bp->quack();
    >>>>> delete bp;
    >>>>> }
    >>>
    >>> Francesco S. Carta wrote:
    >>>> Ah, this makes more sense than my example, but I've been able to
    >>>> make it
    >>>> work even declaring Bar::createCopy() as non-virtual, just for the
    >>>> records.
    >>>
    >>> A question pops up: How exactly did you manage to make Bar::createCopy
    >>> non-virtual? AFAIK, C++ does not allow this.

    >>
    >> I've just copied Stefan's code, pasted it into my editor, deleted the
    >> two "virtual" from createCopy() and quack() within class Bar and
    >> compiled it with MinGW 4.4.0.

    >
    > So the function are still virtual. The virtual keyword in the derived
    > class is superfluous.


    That's what I meant to say with "declaring Bar::createCopy() as
    non-virtual". I guess the keyword is still needed if I want to further
    redefine that function in a further class derived from Bar... isn't it?

    --
    FSC - http://userscripts.org/scripts/show/59948
    http://fscode.altervista.org - http://sardinias.com
     
    Francesco S. Carta, Aug 13, 2010
    #9
  10. , India

    Ian Collins Guest

    On 08/13/10 09:48 PM, Francesco S. Carta wrote:
    > Ian Collins <>, on 13/08/2010 21:41:55, wrote:
    >
    >> On 08/13/10 09:36 PM, Francesco S. Carta wrote:
    >>>>
    >>>> Francesco S. Carta wrote:
    >>>>> Ah, this makes more sense than my example, but I've been able to
    >>>>> make it
    >>>>> work even declaring Bar::createCopy() as non-virtual, just for the
    >>>>> records.
    >>>>
    >>>> A question pops up: How exactly did you manage to make Bar::createCopy
    >>>> non-virtual? AFAIK, C++ does not allow this.
    >>>
    >>> I've just copied Stefan's code, pasted it into my editor, deleted the
    >>> two "virtual" from createCopy() and quack() within class Bar and
    >>> compiled it with MinGW 4.4.0.

    >>
    >> So the function are still virtual. The virtual keyword in the derived
    >> class is superfluous.

    >
    > That's what I meant to say with "declaring Bar::createCopy() as
    > non-virtual". I guess the keyword is still needed if I want to further
    > redefine that function in a further class derived from Bar... isn't it?


    No. Once a virtual, always a virtual. You can't redeclare a virtual
    function as non-virtual.

    --
    Ian Collins
     
    Ian Collins, Aug 13, 2010
    #10
  11. , India wrote:
    > In Stanley Lippman's 'C++ Primer Fourth Edition', in page 564, the
    > following is mentioned:
    >
    > "A virtual function in the derived class can return a reference or
    > pointer to a class that is PUBLICLY derived from the type returned by
    > the base class function."
    >
    > I am unable to understand this sentence. Kindly explain it with
    > program sample.


    I _guess_ that what he is talking about is the so-called co-variance
    feature of C++ (see Stefan van Kessels posting). I have to admit that
    the sentence can be mis-interpreted in many way. To put it better: A
    virtual function f in the class D, which overwrites the same function
    in the base class B, can return a type X that differs from the type Y
    that is returned by B::f as long as Y deprecates to X. [this should
    make it clear that X and Y must be pointers or references to classes
    where Y is publicly derived directly or indirectly from X].

    Regards,
    Stuart
     
    Stuart Redmann, Aug 13, 2010
    #11
  12. Ian Collins <>, on 13/08/2010 21:55:16, wrote:

    > On 08/13/10 09:48 PM, Francesco S. Carta wrote:
    >> Ian Collins <>, on 13/08/2010 21:41:55, wrote:
    >>
    >>> On 08/13/10 09:36 PM, Francesco S. Carta wrote:
    >>>>>
    >>>>> Francesco S. Carta wrote:
    >>>>>> Ah, this makes more sense than my example, but I've been able to
    >>>>>> make it
    >>>>>> work even declaring Bar::createCopy() as non-virtual, just for the
    >>>>>> records.
    >>>>>
    >>>>> A question pops up: How exactly did you manage to make Bar::createCopy
    >>>>> non-virtual? AFAIK, C++ does not allow this.
    >>>>
    >>>> I've just copied Stefan's code, pasted it into my editor, deleted the
    >>>> two "virtual" from createCopy() and quack() within class Bar and
    >>>> compiled it with MinGW 4.4.0.
    >>>
    >>> So the function are still virtual. The virtual keyword in the derived
    >>> class is superfluous.

    >>
    >> That's what I meant to say with "declaring Bar::createCopy() as
    >> non-virtual". I guess the keyword is still needed if I want to further
    >> redefine that function in a further class derived from Bar... isn't it?

    >
    > No. Once a virtual, always a virtual. You can't redeclare a virtual
    > function as non-virtual.


    Ah, very good to know, that will save me some keystrokes in the future
    ;-) Thanks a lot for the clarification.

    --
    FSC - http://userscripts.org/scripts/show/59948
    http://fscode.altervista.org - http://sardinias.com
     
    Francesco S. Carta, Aug 13, 2010
    #12
  13. , India

    Öö Tiib Guest

    On Aug 13, 1:05 pm, "Francesco S. Carta" <> wrote:
    > Ian Collins <>, on 13/08/2010 21:55:16, wrote:
    >
    >
    > > No. Once a virtual, always a virtual. You can't redeclare a virtual
    > > function as non-virtual.

    >
    > Ah, very good to know, that will save me some keystrokes in the future
    > ;-) Thanks a lot for the clarification.


    It is forbidden by some policies to use that "implicit virtuality"
    feature.

    Rationale is that it is already hard to notice that something is
    override of virtual of base of base in C++ and omitted "virtual" makes
    it even simpler to miss. Bugs with polymorphism are causing lot more
    problems in practice than bad memory management.
     
    Öö Tiib, Aug 13, 2010
    #13
  14. , India

    Öö Tiib Guest

    On 13 aug, 23:03, Paavo Helde <> wrote:
    > Öö Tiib <> wrote in news:986f31ea-f0ee-40c0-bad6-
    > :
    >
    >
    >
    > > On Aug 13, 1:05 pm, "Francesco S. Carta" <> wrote:
    > >> Ian Collins <>, on 13/08/2010 21:55:16, wrote:

    >
    > >> > No. Once a virtual, always a virtual. You can't redeclare a virtual
    > >> > function as non-virtual.

    >
    > >> Ah, very good to know, that will save me some keystrokes in the future
    > >> ;-) Thanks a lot for the clarification.

    >
    > > It is forbidden by some policies to use that "implicit virtuality"
    > > feature.

    >
    > > Rationale is that it is already hard to notice that something is
    > > override of virtual of base of base in C++ and omitted "virtual" makes
    > > it even simpler to miss. Bugs with polymorphism are causing lot more
    > > problems in practice than bad memory management.

    >
    > Some compilers have support for declaring explicitly that the function is
    > intended to be a virtual override (eg. MSVC has the 'override' keyword
    > for that). If this is not the case (eg. because of mismatch of the
    > function signature) a compile-time error occurs. I find this feature
    > quite useful, but it means even more keystrokes (and is non-portable).


    It can be perhaps macroed to portable if all in team are ready to use
    it.

    // put into platform specific configuration headers
    #if defined(_MSC_VER) && (_MSC_VER >= 1400) // VS 2005+
    # define OVERRIDE override
    # pragma warning( disable : 4481 ) // nonstandard "override" used
    #else
    # define OVERRIDE
    #endif

    // example code
    struct I
    {
    virtual void f();
    };

    struct X : public I
    {
    void f() OVERRIDE {}
    };
     
    Öö Tiib, Aug 13, 2010
    #14
  15. Öö Tiib <> wrote:
    > #if defined(_MSC_VER) && (_MSC_VER >= 1400) // VS 2005+


    Isn't the first condition kind of redundant?
     
    Juha Nieminen, Aug 14, 2010
    #15
  16. , India

    Öö Tiib Guest

    On 14 aug, 11:05, Juha Nieminen <> wrote:
    > Öö Tiib <> wrote:
    > > #if defined(_MSC_VER) && (_MSC_VER >= 1400) // VS 2005+

    >
    >   Isn't the first condition kind of redundant?


    Yes it is, thanks for noticing. I first wrote that defined part then
    thought that someone may still use MSVC 6.0 or VS 2003. Result didn't
    hurt eye at Friday evening here.
     
    Öö Tiib, Aug 14, 2010
    #16
  17. , India

    James Kanze Guest

    On Aug 13, 9:39 am, "Francesco S. Carta" <> wrote:
    > , India <>, on


    > 13/08/2010 01:29:13, wrote:
    > > In Stanley Lippman's 'C++ Primer Fourth Edition', in page
    > > 564, the following is mentioned:


    > > "A virtual function in the derived class can return
    > > a reference or pointer to a class that is PUBLICLY derived
    > > from the type returned by the base class function."


    > > I am unable to understand this sentence. Kindly explain it
    > > with program sample.


    > IIUIC, that means that if you have a function with signature
    > "virtual Base* Clone() const;" in the base class, then the
    > implementation of the same function in the derived class can
    > be: "Base* Clone() const { return new Derived(*this); }"
    > - just an example that assumes Derived is copy-constructible,
    > of course.


    I don't think that's what is meant (although it's hard to
    say---the sentence is unclear, at least without its surrounding
    context). I think the point here is covariant return types,
    e.g.:

    class Base
    {
    public:
    virtual Base* someFunction();
    };

    class Derived : public Base
    {
    public:
    virtual Derived* someFunction();
    };

    --
    James Kanze
     
    James Kanze, Aug 17, 2010
    #17
  18. , India

    James Kanze Guest

    On Aug 13, 10:09 am, "Francesco S. Carta" <> wrote:
    > Francesco S. Carta <>, on 13/08/2010 10:39:51, wrote:
    > > , India <>, on
    > > 13/08/2010 01:29:13, wrote:


    > >> In Stanley Lippman's 'C++ Primer Fourth Edition', in page 564, the
    > >> following is mentioned:


    > >> "A virtual function in the derived class can return a reference or
    > >> pointer to a class that is PUBLICLY derived from the type returned by
    > >> the base class function."


    > >> I am unable to understand this sentence. Kindly explain it with
    > >> program sample.


    > > IIUIC, that means that if you have a function with signature "virtual
    > > Base* Clone() const;" in the base class, then the implementation of the
    > > same function in the derived class can be: "Base* Clone() const { return
    > > new Derived(*this); }" - just an example that assumes Derived is
    > > copy-constructible, of course.


    > There is either something wrong in that sentence, in my understanding
    > or in my compiler - or my settings thereof - because it allows me to
    > return a pointer to Derived where Base is private:


    In your understanding, I think, because...

    > //-------


    > #include <iostream>


    > using namespace std;


    > class Base {
    > public:
    > Base(int data = 0) : data(data) {};
    > Base(const Base& base) : data(base.data) {};
    > virtual Base* Clone() const {
    > cout << "cloning Base" << endl;
    > return new Base(*this);
    > }
    > int Data() const {
    > return data;
    > }
    > private:
    > int data;
    > };


    > class Derived : private Base {
    > public:
    > Derived(int data = 0) : Base(data) {};
    > Derived(const Derived& derived) : Base(derived) {};
    > Base* Clone() const {


    Here, you're still returning a Base. Any conversion takes place
    in Derived (where the derivation is visible).

    Try changing the return type to Derived*; the compiler should
    complain then.

    See §10.3/5 in the standard for details.

    > cout << "cloning Derived" << endl;
    > return new Derived(*this);
    > }
    > };


    --
    James Kanze
     
    James Kanze, Aug 17, 2010
    #18
  19. , India

    red floyd Guest

    On 8/17/2010 1:54 AM, James Kanze wrote:
    > On Aug 13, 10:09 am, "Francesco S. Carta"<> wrote:
    >> Francesco S. Carta<>, on 13/08/2010 10:39:51, wrote:
    >>> , India<>, on
    >>> 13/08/2010 01:29:13, wrote:

    >
    >>>> In Stanley Lippman's 'C++ Primer Fourth Edition', in page 564, the
    >>>> following is mentioned:

    >
    >>>> "A virtual function in the derived class can return a reference or
    >>>> pointer to a class that is PUBLICLY derived from the type returned by
    >>>> the base class function."

    >
    >>>> I am unable to understand this sentence. Kindly explain it with
    >>>> program sample.

    >
    >>> IIUIC, that means that if you have a function with signature "virtual
    >>> Base* Clone() const;" in the base class, then the implementation of the
    >>> same function in the derived class can be: "Base* Clone() const { return
    >>> new Derived(*this); }" - just an example that assumes Derived is
    >>> copy-constructible, of course.

    >
    >> There is either something wrong in that sentence, in my understanding
    >> or in my compiler - or my settings thereof - because it allows me to
    >> return a pointer to Derived where Base is private:

    >
    > In your understanding, I think, because...
    >
    >> //-------

    >
    >> #include<iostream>

    >
    >> using namespace std;

    >
    >> class Base {
    >> public:
    >> Base(int data = 0) : data(data) {};
    >> Base(const Base& base) : data(base.data) {};
    >> virtual Base* Clone() const {
    >> cout<< "cloning Base"<< endl;
    >> return new Base(*this);
    >> }
    >> int Data() const {
    >> return data;
    >> }
    >> private:
    >> int data;
    >> };

    >
    >> class Derived : private Base {
    >> public:
    >> Derived(int data = 0) : Base(data) {};
    >> Derived(const Derived& derived) : Base(derived) {};
    >> Base* Clone() const {

    >
    > Here, you're still returning a Base. Any conversion takes place
    > in Derived (where the derivation is visible).
    >
    > Try changing the return type to Derived*; the compiler should
    > complain then.
    >
    > See §10.3/5 in the standard for details.
    >


    James, I thought that the compiler should *not* complain if the
    return type of Derived::Clone was Derived*. Isn't that a
    covariant return type?
     
    red floyd, Aug 18, 2010
    #19
  20. , India

    Öö Tiib Guest

    On 18 aug, 02:54, red floyd <> wrote:
    > On 8/17/2010 1:54 AM, James Kanze wrote:
    >
    >
    >
    > > On Aug 13, 10:09 am, "Francesco S. Carta"<>  wrote:
    > >> Francesco S. Carta<>, on 13/08/2010 10:39:51, wrote:
    > >>> , India<>, on
    > >>> 13/08/2010 01:29:13, wrote:

    >
    > >>>> In Stanley Lippman's 'C++ Primer Fourth Edition', in page 564, the
    > >>>> following is mentioned:

    >
    > >>>> "A virtual function in the derived class can return a reference or
    > >>>> pointer to a class that is PUBLICLY derived from the type returned by
    > >>>> the base class function."

    >
    > >>>> I am unable to understand this sentence. Kindly explain it with
    > >>>> program sample.

    >
    > >>> IIUIC, that means that if you have a function with signature "virtual
    > >>> Base* Clone() const;" in the base class, then the implementation of the
    > >>> same function in the derived class can be: "Base* Clone() const { return
    > >>> new Derived(*this); }" - just an example that assumes Derived is
    > >>> copy-constructible, of course.

    >
    > >> There is either something wrong in that sentence, in my understanding
    > >> or in my compiler - or my settings thereof - because it allows me to
    > >> return a pointer to Derived where Base is private:

    >
    > > In your understanding, I think, because...

    >
    > >> //-------

    >
    > >> #include<iostream>

    >
    > >> using namespace std;

    >
    > >> class Base {
    > >>       public:
    > >>       Base(int data = 0) : data(data) {};
    > >>       Base(const Base&  base) : data(base.data) {};
    > >>       virtual Base* Clone() const {
    > >>           cout<<  "cloning Base"<<  endl;
    > >>           return new Base(*this);
    > >>       }
    > >>       int Data() const {
    > >>           return data;
    > >>       }
    > >>       private:
    > >>       int data;
    > >> };

    >
    > >> class Derived : private Base {
    > >>       public:
    > >>       Derived(int data = 0) : Base(data) {};
    > >>       Derived(const Derived&  derived) : Base(derived) {};
    > >>       Base* Clone() const {

    >
    > > Here, you're still returning a Base.  Any conversion takes place
    > > in Derived (where the derivation is visible).

    >
    > > Try changing the return type to Derived*; the compiler should
    > > complain then.

    >
    > > See §10.3/5 in the standard for details.

    >
    > James, I thought that the compiler should *not* complain if the
    > return type of Derived::Clone was Derived*.  Isn't that a
    > covariant return type?


    Did you eyeball §10.3/5? Base is not accessible base class of Derived
    so it is not a covariant there by standard.
     
    Öö Tiib, Aug 18, 2010
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page