Copy a Base Class to a Derived Class

Discussion in 'C++' started by iakko, Jan 12, 2009.

  1. iakko

    iakko Guest

    Hello everybody,
    first of all, sorry if the question I'm about to ask have been already
    answered, but after some hours spent bothering google, I did not work
    it out.

    I have two classes:

    class Base
    {
    public:
    Base() { k = 0; };
    ~Base() {};

    int k;
    void setK(int p) { k = p; };
    int getK() { return k; };

    void myMethod() { /* Code here */ };
    };

    class Derived : public Base
    {
    public:
    Derived() : Base() { i = 0; };
    ~Derived() {};

    int i;
    void setI(int p) { i = p; };
    int getI() { return i; };

    void myCoolMethod() { /* Code here */ };
    };


    Suppose I need to work with the derived class because I have to
    implement many methods and I cannot touch the Base class since it's a
    Qt class.

    What I would like to do is find a way to "merge" an implementation of
    a Derived class with another implementation of Base class, due to have
    all the data for the Base class avaiable in the Derived class.

    Casting is not sufficient since if I cast, I can use the Derived class
    but I will lose all the personal data referred to it.

    Let me explain with an tiny working example:

    /* ### EXAMPLE STARTS ### */
    #include <iostream>

    class Base
    {
    public:
    Base() { k = 0; };
    ~Base() {};

    int k;
    void setK(int p) { k = p; };
    int getK() { return k; };

    void myMethod() { /* Code here */ };
    };

    class Derived : public Base
    {
    public:
    Derived() : Base() { i = 0; };
    ~Derived() {};

    int i;
    void setI(int p) { i = p; };
    int getI() { return i; };

    void myCoolMethod() { /* Code here */ };
    };

    int main() {
    Derived * d = new Derived();

    d->setI(10);
    printf("i: %d\n", d->getI());
    /* prints 10 */

    Base * b = new Base();

    b->setK(2);
    printf("k: %d\n", b->getK());
    /* prints 2 */

    d = reinterpret_cast<Derived *>(b);

    printf("i: %d -- k: %d\n", d->getI(), d->getK());
    /* prints 0 -- 2 !!! I want 10 -- 2 !!!*/

    return 0;
    }
    /* ### EXAMPLE STOPS ### */

    Casting from Base to Derived loses all the Derived class information!!

    I feel like there is a solution but I cannot imagine what is it.

    Any suggestion is appreciated, thanks.

    --
    Iacopo
    iakko, Jan 12, 2009
    #1
    1. Advertising

  2. iakko

    Guest

    On 12 Jan, 16:02, iakko <> wrote:

    I think you need to have a bit of a think about what you are trying to
    do. If you're still confused, come back to us with a bit more detail.

    > /* ### EXAMPLE STARTS ### */
    > #include <iostream>
    >
    > class Base
    > {
    > public:
    >         Base() { k = 0; };
    >         ~Base() {};
    >
    >         int k;
    >         void setK(int p) { k = p; };
    >         int getK() { return k; };
    >
    >         void myMethod() { /* Code here */ };
    >
    > };


    I presume that eventually k will be private - otherwise, you don't
    really need the get and set. But this is not your main problem.

    > class Derived : public Base
    > {
    > public:
    >         Derived() : Base() { i = 0; };
    >         ~Derived() {};
    >
    >         int i;
    >         void setI(int p) { i = p; };
    >         int getI() { return i; };
    >
    >         void myCoolMethod() { /* Code here */ };
    >
    > };
    >
    > int main() {
    >         Derived * d = new Derived();
    >
    >         d->setI(10);
    >         printf("i: %d\n", d->getI());
    >         /* prints 10 */


    OK. So far you have created a new Derived. This doesn't have a name as
    such, but I will call it D for future reference. You have set D.i to
    10, and you have a pointer (of type pointer-to-Derived) d which points
    to D.

    >         Base * b = new Base();
    >
    >         b->setK(2);
    >         printf("k: %d\n", b->getK());
    >         /* prints 2 */


    Now you also have a Base, which I will call B. B.k is set to 2. A
    pointer b, of type pointer-to-base, points at B.

    >         d = reinterpret_cast<Derived *>(b);


    What you are trying to do here is make d point at B. This is a bad
    idea, as d is a pointer-to-derived and B is a Base, not a Derived. But
    also, if it did work, you wouldn't have anything pointing at D, so you
    would lose its information.

    >         printf("i: %d -- k: %d\n", d->getI(), d->getK());
    >         /* prints 0 -- 2 !!! I want 10 -- 2 !!!*/


    I don't follow what you are trying to do here. You have set D.i to 10,
    but you haven't set B.i, which doesn't exist. You have stored the
    value 10 in one place and then pointed d at a different place. If you
    want d->getI() to give you a result of 10, you need to point d at a
    Derived (or something derived from a Derived) and you need to store
    the 10 in the same object that you retrieve it from later. Your
    present code stores the value in D but tries to find it again in B.

    Hope this helps.
    Paul.
    , Jan 12, 2009
    #2
    1. Advertising

  3. On Jan 12, 4:02 pm, iakko <> wrote:
    > [...]
    > Suppose I need to work with the derived class because I have to
    > implement many methods and I cannot touch the Base class since it's a
    > Qt class.
    >
    > What I would like to do is find a way to "merge" an implementation of
    > a Derived class with another implementation of Base class, due to have
    > all the data for the Base class avaiable in the Derived class.
    >
    > [erroneous code snipped]


    You cannot retrofit an object at runtime. You will have to study the
    Qt library and find out were and how the object is created and whether
    you can make it create an object of your derived class instead. If so
    you can use downcasting (dynamic_cast)to access the extra members of
    your derived class whenever the library gives you a base class pointer
    or reference to that object.

    Regards,
    Vidar Hasfjord
    Vidar Hasfjord, Jan 12, 2009
    #3
  4. iakko

    Daniel Pitts Guest

    iakko wrote:
    > Hello everybody,
    > first of all, sorry if the question I'm about to ask have been already
    > answered, but after some hours spent bothering google, I did not work
    > it out.
    >
    > I have two classes:
    >
    > class Base
    > {
    > public:
    > Base() { k = 0; };
    > ~Base() {};
    >
    > int k;
    > void setK(int p) { k = p; };
    > int getK() { return k; };
    >
    > void myMethod() { /* Code here */ };
    > };
    >
    > class Derived : public Base
    > {
    > public:
    > Derived() : Base() { i = 0; };
    > ~Derived() {};
    >
    > int i;
    > void setI(int p) { i = p; };
    > int getI() { return i; };
    >
    > void myCoolMethod() { /* Code here */ };
    > };
    >
    >
    > Suppose I need to work with the derived class because I have to
    > implement many methods and I cannot touch the Base class since it's a
    > Qt class.
    >
    > What I would like to do is find a way to "merge" an implementation of
    > a Derived class with another implementation of Base class, due to have
    > all the data for the Base class avaiable in the Derived class.
    >
    > Casting is not sufficient since if I cast, I can use the Derived class
    > but I will lose all the personal data referred to it.
    >
    > Let me explain with an tiny working example:
    >
    > /* ### EXAMPLE STARTS ### */
    > #include <iostream>
    >
    > class Base
    > {
    > public:
    > Base() { k = 0; };
    > ~Base() {};
    >
    > int k;
    > void setK(int p) { k = p; };
    > int getK() { return k; };
    >
    > void myMethod() { /* Code here */ };
    > };
    >
    > class Derived : public Base
    > {
    > public:
    > Derived() : Base() { i = 0; };
    > ~Derived() {};
    >
    > int i;
    > void setI(int p) { i = p; };
    > int getI() { return i; };
    >
    > void myCoolMethod() { /* Code here */ };
    > };
    >
    > int main() {
    > Derived * d = new Derived();
    >
    > d->setI(10);
    > printf("i: %d\n", d->getI());
    > /* prints 10 */
    >
    > Base * b = new Base();
    >
    > b->setK(2);
    > printf("k: %d\n", b->getK());
    > /* prints 2 */
    >
    > d = reinterpret_cast<Derived *>(b);
    >
    > printf("i: %d -- k: %d\n", d->getI(), d->getK());
    > /* prints 0 -- 2 !!! I want 10 -- 2 !!!*/
    >
    > return 0;
    > }
    > /* ### EXAMPLE STOPS ### */
    >
    > Casting from Base to Derived loses all the Derived class information!!
    >
    > I feel like there is a solution but I cannot imagine what is it.
    >
    > Any suggestion is appreciated, thanks.
    >
    > --
    > Iacopo


    Try this instead:
    int main() {
    Derived * d = new Derived();

    d->setI(10);
    printf("i: %d\n", d->getI());
    /* prints 10 */

    Base * b = d;

    b->setK(2);
    printf("k: %d\n", b->getK());
    /* prints 2 */

    d = reinterpret_cast<Derived *>(b);

    printf("i: %d -- k: %d\n", d->getI(), d->getK());
    /* prints 2 -- 2 */

    return 0;
    }

    There is a difference between classes and instances! Make sure not to
    confuse the two. When you have "new Derived()", you have actually
    created a new Base along with a new Derived, so you don't need to have
    another new Base();
    --
    Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
    Daniel Pitts, Jan 12, 2009
    #4
  5. iakko

    iakko Guest

    On 12 Gen, 21:06, Daniel Pitts
    <> wrote:

    > There is a difference between classes and instances! Make sure not to
    > confuse the two.  When you have "new Derived()", you have actually
    > created a new Base along with a new Derived, so you don't need to have
    > another new Base();
    > --


    That's not what I'm looking for. Suppose that the Base class is
    produced by another class that I cannot modify. Suppose that I can
    only use instances of a Derived class of Base. Thus, I can only make
    an instance of Derived class and handle an already instanced Base
    class. That's the scenario:

    int main()
    {
    /* Cannot touch from here ... */

    Base * b = new Base();
    b->setK(2);
    printf("k: %d\n", b->getK());
    /* prints 0 -- 2 */

    /* ... to here! */

    Derived * d = new Derived();

    d->setI(10);
    printf("i: %d\n", d->getI());
    /* prints 10 -- 0 */

    b = d; /* ??? Doesn't work */
    d = b; /* ??? It's the same, doesn't work */

    printf("i: %d -- k: %d\n", d->getI(), d->getK());
    /* prints 10 -- 0 or 0 -- 2, it depends on b = d or d = b */

    return 0;
    }

    Doesn't work.

    Seems like the c++ language does not allow this behavior, but it's
    logically plausible.

    Suppose you have a Server class with a method that produces a Socket
    class needed to handle connections. Suppose you want to inherit the
    Socket class to generate Connection classes.

    /* Pseudo code here, no implementations of methods */

    class Server {
    public:
    Server(); ~Server();
    Socket * incomingConnection();
    };

    class Connection : public Socket
    {
    public:
    Socket(); ~Socket();
    };

    int main () {
    Server srv;
    Socket * mySck = new Socket();

    for(;;) {
    mySck = reinterpret_cast<Connection *>
    (srv.incomingConnection());
    }

    /* mySck loses al the informations, takes the entire data of
    the Socket class returned by srv.incomingConnection(); */
    }

    In this scenario, deriving a Connection class is extremely useful! The
    only way should be that srv.incomingConnection() returns a Connection
    derived class filled whit data. I cannot do that because it belongs to
    the untouchable library.

    Maybe my english is not good enough to explain what I mean, but I hope
    that the example can make it clearer.

    Thanks anyway for your time :)

    --
    Iacopo
    iakko, Jan 13, 2009
    #5
  6. iakko

    iakko Guest

    On 12 Gen, 19:20, wrote:

    > I don't follow what you are trying to do here. You have set D.i to 10,
    > but you haven't set B.i, which doesn't exist. You have stored the
    > value 10 in one place and then pointed d at a different place. If you
    > want d->getI() to give you a result of 10, you need to point d at a
    > Derived (or something derived from a Derived) and you need to store
    > the 10 in the same object that you retrieve it from later. Your
    > present code stores the value in D but tries to find it again in B.
    >
    > Hope this helps.
    > Paul.


    Yes! That's right. What I would like to do is merging a pre-existing
    base class data inside an instanced derived one.
    It's like you already have a base class instance and you generate a
    derived class instance. So you have two instances, but I want to merge
    them together.
    Sounds better ?

    --
    Iacopo
    iakko, Jan 13, 2009
    #6
  7. iakko

    LR Guest

    iakko wrote:
    > On 12 Gen, 21:06, Daniel Pitts
    > <> wrote:
    >
    >> There is a difference between classes and instances! Make sure not to
    >> confuse the two. When you have "new Derived()", you have actually
    >> created a new Base along with a new Derived, so you don't need to have
    >> another new Base();
    >> --

    >
    > That's not what I'm looking for. Suppose that the Base class is
    > produced by another class that I cannot modify. Suppose that I can
    > only use instances of a Derived class of Base. Thus, I can only make
    > an instance of Derived class and handle an already instanced Base
    > class. That's the scenario:



    Is inheritance really what you want to do? I'm going to guess that the
    class that you're inheriting from doesn't have a virtual dtor and might
    need one.

    >
    > int main()
    > {
    > /* Cannot touch from here ... */
    >
    > Base * b = new Base();
    > b->setK(2);
    > printf("k: %d\n", b->getK());
    > /* prints 0 -- 2 */
    >
    > /* ... to here! */
    >
    > Derived * d = new Derived();
    >
    > d->setI(10);
    > printf("i: %d\n", d->getI());
    > /* prints 10 -- 0 */
    >
    > b = d; /* ??? Doesn't work */
    > d = b; /* ??? It's the same, doesn't work */


    You want to assign pointers of different types to each other?


    >
    > printf("i: %d -- k: %d\n", d->getI(), d->getK());
    > /* prints 10 -- 0 or 0 -- 2, it depends on b = d or d = b */


    d and b point to different objects.


    >
    > return 0;
    > }
    >
    > Doesn't work.
    >
    > Seems like the c++ language does not allow this behavior, but it's
    > logically plausible.


    If you want to modify the int in Base that is inherited by derived, have
    you considered something like this?
    #include <iostream>
    class Base {
    int i;
    public:
    void SetI(const int ii) { i = ii; }
    int GetI() const { return i; }
    };
    class Derived : public Base {
    public:
    void SetI(const int ii) { Base::SetI(ii); }
    int GetI() const { return Base::GetI(); }
    };
    int main() {
    Derived d;
    d.SetI(34);
    std::cout << d.GetI() << std::endl;
    }



    >
    > Suppose you have a Server class with a method that produces a Socket
    > class needed to handle connections. Suppose you want to inherit the
    > Socket class to generate Connection classes.
    >
    > /* Pseudo code here, no implementations of methods */
    >
    > class Server {
    > public:
    > Server(); ~Server();
    > Socket * incomingConnection();
    > };
    >
    > class Connection : public Socket
    > {
    > public:
    > Socket(); ~Socket();


    I don't understand this, you have a ctor and a dtor for Socket in the
    Connection class?

    > };
    >
    > int main () {
    > Server srv;
    > Socket * mySck = new Socket();
    >
    > for(;;) {
    > mySck = reinterpret_cast<Connection *>
    > (srv.incomingConnection());
    > }
    >
    > /* mySck loses al the informations, takes the entire data of
    > the Socket class returned by srv.incomingConnection(); */
    > }
    >
    > In this scenario, deriving a Connection class is extremely useful! The
    > only way should be that srv.incomingConnection() returns a Connection
    > derived class filled whit data. I cannot do that because it belongs to
    > the untouchable library.
    >
    > Maybe my english is not good enough to explain what I mean, but I hope
    > that the example can make it clearer.
    >
    > Thanks anyway for your time :)



    I'm pretty sure that I don't follow all of that, but maybe what you want
    is something like this:

    class SocketWeCantTouch {};
    class ServerWeCantTouch {
    public:
    SocketWeCantTouch *socket() const {
    // who owns this?
    // many details are missing, so I don't know
    // but we might not want to delete this thing
    // ourselves but let the classes we can't touch
    // do it for us.
    return new SocketWeCantTouch;
    }
    };

    class Connection {
    SocketWeCantTouch *p_;
    public:
    Connection(const ServerWeCantTouch &s)
    :
    p_ (s.socket())
    {}
    ~Connection() {
    delete p_; // wait a minute, who owns this?
    }
    SocketWeCantTouch *p() const { return p_; }
    };

    int main() {
    const ServerWeCantTouch server;

    for(;;) {
    const Connection c(server);
    }
    }


    LR
    LR, Jan 13, 2009
    #7
  8. iakko

    iakko Guest

    On 13 Gen, 01:51, LR <> wrote:

    > You want to assign pointers of different types to each other?


    No. That was an example showing that what Daniel Pitts said was not
    the answer.

    > If you want to modify the int in Base that is inherited by derived, have
    > you considered something like this?
    > #include <iostream>
    > class Base {
    >     int i;
    > public:
    >     void SetI(const int ii) { i = ii; }
    >     int GetI() const { return i; }};
    >
    > class Derived : public Base {
    > public:
    >     void SetI(const int ii) { Base::SetI(ii); }
    >     int GetI() const { return Base::GetI(); }};
    >
    > int main() {
    >     Derived d;
    >     d.SetI(34);
    >     std::cout << d.GetI() << std::endl;
    >
    >
    >
    > }


    Well, it's an ugly workaround, because I'm going to reimplement all
    the methods I need (maybe many), without reason. Usually, when you
    want to reimplement a method from base class, it's due to the fact
    that you need to add code inside for different behavior, in this case
    it's only a call. This is against the inheritance purpose!

    > > Suppose you have a Server class with a method that produces a Socket
    > > class needed to handle connections. Suppose you want to inherit the
    > > Socket class to generate Connection classes.

    >
    > > /* Pseudo code here, no implementations of methods */

    >
    > > class Server {
    > > public:
    > >         Server(); ~Server();
    > >         Socket * incomingConnection();
    > > };

    >
    > > class Connection : public Socket
    > > {
    > > public:
    > >         Socket(); ~Socket();

    >
    > I don't understand this, you have a ctor and a dtor for Socket in the
    > Connection class?
    >
    >
    >
    > > };

    >
    > > int main () {
    > >         Server srv;
    > >         Socket * mySck = new Socket();

    >
    > >         for(;;) {
    > >             mySck = reinterpret_cast<Connection *>
    > > (srv.incomingConnection());
    > >         }

    >
    > >         /* mySck loses al the informations, takes the entire data of
    > > the Socket class returned by srv.incomingConnection(); */
    > > }

    >
    > > In this scenario, deriving a Connection class is extremely useful! The
    > > only way should be that srv.incomingConnection() returns a Connection
    > > derived class filled whit data. I cannot do that because it belongs to
    > > the untouchable library.

    >
    > > Maybe my english is not good enough to explain what I mean, but I hope
    > > that the example can make it clearer.

    >
    > > Thanks anyway for your time :)

    >
    > I'm pretty sure that I don't follow all of that, but maybe what you want
    > is something like this:
    >
    > class SocketWeCantTouch {};
    > class ServerWeCantTouch {
    > public:
    >     SocketWeCantTouch *socket() const {
    >         // who owns this?
    >         // many details are missing, so I don't know
    >         // but we might not want to delete this thing
    >         // ourselves but let the classes we can't touch
    >         // do it for us.
    >         return new SocketWeCantTouch;
    >     }
    >
    > };
    >
    > class Connection {
    >     SocketWeCantTouch *p_;
    > public:
    >     Connection(const ServerWeCantTouch &s)
    >     :
    >     p_ (s.socket())
    >     {}
    >     ~Connection() {
    >         delete p_; // wait a minute, who owns this?
    >     }
    >     SocketWeCantTouch *p() const { return p_; }
    >
    > };
    >
    > int main() {
    >     const ServerWeCantTouch server;
    >
    >     for(;;) {
    >         const Connection c(server);
    >     }
    >
    > }
    >
    > LR


    In this way, I lose the inheritance property, which is important for
    me. You are simply storing a pointer to the base class, ready for
    calling when you need it. That's absolutely correct but not what I'm
    looking for. (Actually, this is the current implementation I use, but
    I'm looking for a different one)

    I wish I had a more deeper known of English to explain better, it's so
    simple to imagine what I'm saying.

    Suppose you have an array of two items [A, x], [0, B]. the 'x' means
    that you don't care what is in there.
    Suppose you want to merge the two arrays due to have a final one like
    this: [A, B]. You cannot simply replace the items, otherwise you will
    delete some data:


    ------- ------- -------
    | | | | | |
    | A | | 0 | | 0 |
    | | | | | |
    ------- <-- ------- = -------
    | | | | | |
    | x | | B | | B |
    | | | | | |
    ------- ------- -------

    or

    ------- ------- -------
    | | | | | |
    | A | | 0 | | A |
    | | | | | |
    ------- --> ------- = -------
    | | | | | |
    | x | | B | | x |
    | | | | | |
    ------- ------- -------

    I would like to have:

    ------- ------- -------
    | | | | | |
    | A | | 0 | | A |
    | | | | | |
    ------- (+) ------- = -------
    | | | | | |
    | x | | B | | B |
    | | | | | |
    ------- ------- -------

    Imagine the first array as the derived class and the second as the
    base class. I want a way to copy the entire data of the base class
    inside the implementation of the derived class. That's sounds
    credible.
    Can you figure it out now? Maybe it's the most silly example in the
    history of examples.. ever :)

    --
    Iacopo
    iakko, Jan 13, 2009
    #8
  9. On Jan 13, 12:03 am, iakko <> wrote:
    > On 12 Gen, 21:06, Daniel Pitts
    > [...]
    > Suppose that the Base class is
    > produced by another class that I cannot modify. Suppose that I can
    > only use instances of a Derived class of Base. Thus, I can only make
    > an instance of Derived class and handle an already instanced Base
    > class.
    > [...]


    In that case inheritance is not the solution.

    If I understand correctly, what you basically want is to associate
    extra information with an object created by an untouchable library.
    You can only do that by inheritance if you can control the creation of
    objects; as pointed out in my other reply.

    That said, there are other ways of associating extra information with
    an object. Often library classes provide a hook were you can attach
    data. The typical example is an event handler, where extra data is
    often called the "context":

    // Event handler registration

    void handler (Event*, void* context); // declaration
    MyHandler* h = /*...*/; // associated object
    server.setEventHandler (
    incoming_connection_event,
    &handler,
    static_cast <void*> (h) // context
    );

    // Handler definition

    void handler (Event* e, void* context) {
    MyHandler* h =
    reinterpret_cast <MyHandler*> (context);
    h->handleConnection (e); // forward
    }

    If the library doesn't provide such hooks, you can associate your
    extra information with an existing object by using an associative data
    structure. For example:

    // Event handler registration

    void handler (Event*); // Note: No context parameter.
    MyHandler* h = /*...*/; // associated object
    map <EventId, MyHandler*> m;
    m [incoming_connection_event] = h;
    server.setEventHandler (
    incoming_connection_event,
    &handler
    );

    // Handler definition

    void handler (Event* e) {
    MyConnection* c = m [e->getId ()];
    c->handleConnection (e); // forward
    }

    I hope that's helpful.

    Regards,
    Vidar Hasfjord
    Vidar Hasfjord, Jan 13, 2009
    #9
  10. iakko

    iakko Guest

    On 13 Gen, 10:52, Vidar Hasfjord <> wrote:

    > If the library doesn't provide such hooks, you can associate your
    > extra information with an existing object by using an associative data
    > structure.


    Sure, I've already found an alternative, but I'm trying to realize if
    I'm crazy or I'm just finding out a limit of C++.
    I'm saying that because I did an example (that runs) that realizes
    what I'm saying, let's take a look:

    /* ### ESAMPLE STARTS ### */

    #include <iostream>

    class Base
    {
    public:
    Base() { k = 0; };
    ~Base() {};

    int k;
    void setK(int p) { k = p; };
    int getK() { return k; };

    void myMethod() { /* Code here */ };
    };

    class Derived : public Base
    {
    public:
    Derived() : Base() { i = 0; };
    ~Derived() {};

    int i;
    void setI(int p) { i = p; };
    int getI() { return i; };

    void myCoolMethod() { /* Code here */ };
    };

    int main() {
    Base * b = new Base();

    b->setK(2);
    printf("k: %d\n", b->getK());

    Derived * d = new Derived();

    d->setI(10);
    printf("i: %d\n", d->getI());

    d = (Derived *)memcpy(d, b, sizeof(b));

    printf("i: %d -- k: %d\n", d->getI(), d->getK());

    return 0;
    }

    /* ### ESAMPLE STOPS ### */

    Focus this line:

    d = (Derived *)memcpy(d, b, sizeof(b));

    Sounds crazy but it does what I'm saying. It replaces memory inside
    the Derived space stored for the inheritance, with the values stored
    by the Base class. In this way, you have a merge between the two
    classes, for free!

    Now the question is: Am I lucky or can it be a real solution? Can it
    work in general, with multiple inheritance too?

    I tried it only in linux, on other systems may fail.

    --
    Iacopo
    iakko, Jan 13, 2009
    #10
  11. iakko

    Guest

    On 13 Jan, 00:07, iakko <> wrote:
    > What I would like to do is merging a pre-existing
    > base class data inside an instanced derived one.
    > It's like you already have a base class instance and you generate a
    > derived class instance. So you have two instances, but I want to merge
    > them together.
    > Sounds better ?


    Do you need to have the Derived already existing, with "don't care"
    data, before you get involved with the Base? If not, things may be
    easier.

    One possible solution would be to have a constructor that copies all
    the relevant parts of the Base. For instance, do:

    Derived(Base& in) : Base(in) { i = 0; };

    which, if I've got the syntax right, allows you to do:

    Base * b = new Base();
    b->setK(2);
    Derived * d = new Derived(b);


    Alternatively, you might do best having a new class which simply
    points at a Base, for instance:

    class Holder
    {
    public:
    int i;
    Base *b;
    };

    Hope this helps.
    Paul.
    , Jan 13, 2009
    #11
  12. iakko

    iakko Guest

    On 13 Gen, 14:06, wrote:

    > Do you need to have the Derived already existing, with "don't care"
    > data, before you get involved with the Base? If not, things may be
    > easier.


    I make an instance of the Derived and get the Base from elsewhere.
    Both are important.

    > One possible solution would be to have a constructor that copies all
    > the relevant parts of the Base. For instance, do:


    Consider that the Derived class is quite complex, has no sense to
    copy, I can use the methods I need just reimplementing a Derived
    method that maps it.
    Your suggestion is the faster, you are right. Actually, I'm using this
    way right now.
    Thanks anyway :)

    --
    Iacopo
    iakko, Jan 13, 2009
    #12
  13. On Jan 13, 11:26 am, iakko <> wrote:
    > On 13 Gen, 10:52, Vidar Hasfjord <> wrote:
    > Sure, I've already found an alternative, but I'm trying to realize if
    > I'm crazy or I'm just finding out a limit of C++.


    Good. And, yes, you are finding the limits of C++.

    > Focus this line:
    >
    >     d = (Derived *)memcpy(d, b, sizeof(b));
    >
    > Sounds crazy but it does what I'm saying.


    It doesn't buy you anything though. What you have created is a new
    object pointed to by 'd' that contains some copied parts of a Base
    object; a Frankenstein monster with undefined behaviour. You can make
    it come alive, but you have no guarantees from the C++ standard or the
    compiler. In fact, see Paul's reply for how you can safely and easily
    copy the base part to a new derived object.

    Neither solves the problem though. The essential point is that the
    original Base object; which in your problem statement is owned and
    handled by the untouchable library; is still unchanged and not
    associated with your additional data. For example, you cannot use this
    technique to pass along extra data in the handler example in my
    previous post.

    So your technique doesn't solve any problems; and worse; it is not
    reliable.

    Regards,
    Vidar Hasfjord
    Vidar Hasfjord, Jan 13, 2009
    #13
  14. iakko

    LR Guest

    iakko wrote:
    > On 13 Gen, 01:51, LR <> wrote:





    >> class SocketWeCantTouch {};
    >> class ServerWeCantTouch {
    >> public:
    >> SocketWeCantTouch *socket() const {
    >> // who owns this?
    >> // many details are missing, so I don't know
    >> // but we might not want to delete this thing
    >> // ourselves but let the classes we can't touch
    >> // do it for us.
    >> return new SocketWeCantTouch;
    >> }
    >>
    >> };
    >>
    >> class Connection {
    >> SocketWeCantTouch *p_;
    >> public:
    >> Connection(const ServerWeCantTouch &s)
    >> :
    >> p_ (s.socket())
    >> {}
    >> ~Connection() {
    >> delete p_; // wait a minute, who owns this?
    >> }
    >> SocketWeCantTouch *p() const { return p_; }
    >>
    >> };
    >>
    >> int main() {
    >> const ServerWeCantTouch server;
    >>
    >> for(;;) {
    >> const Connection c(server);
    >> }
    >>
    >> }
    >>
    >> LR

    >
    > In this way, I lose the inheritance property, which is important for
    > me.


    Why? You're using inheriting a class that you can't control, and none
    of your examples have shown a virtual dtor or any virtual member
    functions. That would worry me.

    How much behavior are you adding through your use of inheritance? Why do
    you have to inherit?


    > You are simply storing a pointer to the base class, ready for
    > calling when you need it. That's absolutely correct but not what I'm
    > looking for. (Actually, this is the current implementation I use, but
    > I'm looking for a different one)


    Is there some reason why you can't return either a pointer like,
    SocketWeCantTouch *Connection::p();
    or a reference
    SocketWeCantTouch &Connection::r();

    and then use them like this
    Connection c(server);
    c.r().someSocketMethod();
    c.p()->someSocketMethod();



    >
    > I wish I had a more deeper known of English to explain better, it's so
    > simple to imagine what I'm saying.
    >
    > Suppose you have an array of two items [A, x], [0, B]. the 'x' means
    > that you don't care what is in there.
    > Suppose you want to merge the two arrays due to have a final one like
    > this: [A, B]. You cannot simply replace the items, otherwise you will
    > delete some data:


    You can't replace the items? Are they pointers to something? Can they
    be copied? Can they be swaped?





    > Imagine the first array as the derived class and the second as the
    > base class. I want a way to copy the entire data of the base class
    > inside the implementation of the derived class. That's sounds
    > credible.


    Does your base class have a swap member?

    > Can you figure it out now? Maybe it's the most silly example in the
    > history of examples.. ever :)


    I feel like I'm getting closer to understanding what you want, but I'm
    not sure that it's a good idea.

    I suspect that coupling a class that you don't have much control over
    through inheritance isn't a great idea. YMWV.

    LR
    LR, Jan 13, 2009
    #14
  15. iakko

    iakko Guest

    On 13 Gen, 15:08, Vidar Hasfjord <> wrote:

    > It doesn't buy you anything though. What you have created is a new
    > object pointed to by 'd' that contains some copied parts of a Base
    > object; a Frankenstein monster with undefined behaviour. You can make
    > it come alive, but you have no guarantees from the C++ standard or the
    > compiler. In fact, see Paul's reply for how you can safely and easily
    > copy the base part to a new derived object.


    Absolutely :D I did more experiments and doesn't work. It was just an
    experiment :)

    > Neither solves the problem though. The essential point is that the
    > original Base object; which in your problem statement is owned and
    > handled by the untouchable library; is still unchanged and not
    > associated with your additional data. For example, you cannot use this
    > technique to pass along extra data in the handler example in my
    > previous post.
    >
    > So your technique doesn't solve any problems; and worse; it is not
    > reliable.


    Ehi man, I never said "you folks out there doesn't know nothing about C
    ++, listen to me" :) I write in this list with the hope that all the
    people that answer me have a very very deeper know-how about those
    subject than me.

    My "solution" is nothing, but I think that what I have in mind is not
    so crazy.

    > Regards,
    > Vidar Hasfjord
    iakko, Jan 13, 2009
    #15
  16. iakko

    iakko Guest

    On 13 Gen, 16:07, LR <> wrote:

    > Why?  You're using inheriting a class that you can't control, and none
    > of your examples have shown a virtual dtor or any virtual member
    > functions.  That would worry me.


    I was showing what I would like, not what is right.
    As I said, the current implementation uses this way.

    > How much behavior are you adding through your use of inheritance? Why do
    > you have to inherit?


    I have to implement many more methods, having the control of the base
    class. Using the pointer is the same, but I was thinking about a way
    to avoid this situation. What I have in mind is maybe a more elegant
    use.

    > Is there some reason why you can't return either a pointer like,
    >      SocketWeCantTouch *Connection::p();
    > or a reference
    >      SocketWeCantTouch &Connection::r();
    >
    > and then use them like this
    >     Connection c(server);
    >     c.r().someSocketMethod();
    >     c.p()->someSocketMethod();


    Read above.

    > You can't replace the items?  Are they pointers to something? Can they
    > be copied? Can they be swaped?


    Is not "I can't", but "I don't want!". If I have the pointer, there is
    no reason to copy data. I can use methods from the base class (from
    the stored pointer).

    > Does your base class have a swap member?


    Why?

    > I feel like I'm getting closer to understanding what you want, but I'm
    > not sure that it's a good idea.


    Why not?

    > I suspect that coupling a class that you don't have much control over
    > through inheritance isn't a great idea.  YMWV.


    Why not?

    --
    Iacopo
    iakko, Jan 13, 2009
    #16
  17. iakko

    Bertrand Guest

    iakko wrote:
    > On 13 Gen, 15:08, Vidar Hasfjord <> wrote:
    >
    >> It doesn't buy you anything though. What you have created is a new
    >> object pointed to by 'd' that contains some copied parts of a Base
    >> object; a Frankenstein monster with undefined behaviour. You can make
    >> it come alive, but you have no guarantees from the C++ standard or the
    >> compiler. In fact, see Paul's reply for how you can safely and easily
    >> copy the base part to a new derived object.

    >
    > Absolutely :D I did more experiments and doesn't work. It was just an
    > experiment :)
    >
    >> Neither solves the problem though. The essential point is that the
    >> original Base object; which in your problem statement is owned and
    >> handled by the untouchable library; is still unchanged and not
    >> associated with your additional data. For example, you cannot use this
    >> technique to pass along extra data in the handler example in my
    >> previous post.
    >>
    >> So your technique doesn't solve any problems; and worse; it is not
    >> reliable.

    >
    > Ehi man, I never said "you folks out there doesn't know nothing about C
    > ++, listen to me" :) I write in this list with the hope that all the
    > people that answer me have a very very deeper know-how about those
    > subject than me.
    >
    > My "solution" is nothing, but I think that what I have in mind is not
    > so crazy.
    >
    >> Regards,
    >> Vidar Hasfjord

    >

    if you want to assign just the base class, you can use (providing it's
    available):
    d->Base::eek:perator=( *b );
    bear in mind that *d contains a *copy* of *b, they are two different
    objects. in any case, and in agreement with the previous posts on this
    thread, it's almost surely incorrect for what you want. but I just felt
    I would mention it. ;-)

    --
    Bertrand
    Bertrand, Jan 14, 2009
    #17
  18. iakko

    LR Guest

    iakko wrote:
    > On 13 Gen, 16:07, LR <> wrote:
    >
    >> Why? You're using inheriting a class that you can't control, and none
    >> of your examples have shown a virtual dtor or any virtual member
    >> functions. That would worry me.

    >
    > I was showing what I would like, not what is right.
    > As I said, the current implementation uses this way.
    >
    >> How much behavior are you adding through your use of inheritance? Why do
    >> you have to inherit?

    >
    > I have to implement many more methods, having the control of the base
    > class. Using the pointer is the same, but I was thinking about a way
    > to avoid this situation. What I have in mind is maybe a more elegant
    > use.
    >
    >> Is there some reason why you can't return either a pointer like,
    >> SocketWeCantTouch *Connection::p();
    >> or a reference
    >> SocketWeCantTouch &Connection::r();
    >>
    >> and then use them like this
    >> Connection c(server);
    >> c.r().someSocketMethod();
    >> c.p()->someSocketMethod();

    >
    > Read above.


    I have, please tell me why this is unacceptable.


    >> You can't replace the items? Are they pointers to something? Can they
    >> be copied? Can they be swaped?

    >
    > Is not "I can't", but "I don't want!". If I have the pointer, there is
    > no reason to copy data. I can use methods from the base class (from
    > the stored pointer).


    But not through inheritance, since AFAIK, you cannot inherit from a
    pointer in C++.

    Maybe something like the proxy pattern would be useful?

    >
    >> Does your base class have a swap member?

    >
    > Why?


    You could use that method to replace the Base class in the derived
    class, but you don't want to do that.

    >
    >> I feel like I'm getting closer to understanding what you want, but I'm
    >> not sure that it's a good idea.

    >
    > Why not?


    Perhaps I should have said I'm pretty sure that what you want to do
    isn't feasible in C++.


    >> I suspect that coupling a class that you don't have much control over
    >> through inheritance isn't a great idea. YMWV.

    >
    > Why not?


    It might not be written to be inherited from. If the author/owner of
    that class expected that the class wouldn't be inherited from, then who
    knows but that at some time in the future they'll change the class in a
    way that will create some problem if you have inherited from it. But
    this is based on an expectation I have about a class I haven't seen.
    LR, Jan 14, 2009
    #18
  19. iakko

    iakko Guest

    On 14 Gen, 05:59, LR <> wrote:

    > I have, please tell me why this is unacceptable.


    I didn't say that it's not unacceptable! If you read carefully, I said
    that you consideration is correct and I'm using it right now :)

    > But not through inheritance, since AFAIK, you cannot inherit from a
    > pointer in C++.


    Sure! Pointers are just numbers :) I'm saying that I would like to
    know if there is a way to "replace" a base class of a derived one with
    another instance!
    This is not against the purpose of the class creator. If you inherit a
    class, you can use it as the base class, without problems. The fact is
    that I get a base class already "filled" and I would like to use it as
    a derived one. I don't know how to expose it better :/

    > Maybe something like the proxy pattern would be useful?


    Don't know about this pattern, I'll take a look.

    > You could use that method to replace the Base class in the derived
    > class, but you don't want to do that.


    It's exactly what I want to do! Can you clarify this point please ?

    > Perhaps I should have said I'm pretty sure that what you want to do
    > isn't feasible in C++.


    Perhaps I didn't not explain it in the proper way, I think it's not a
    so crazy idea.

    > It might not be written to be inherited from.  If the author/owner of
    > that class expected that the class wouldn't be inherited from, then who
    > knows but that at some time in the future they'll change the class in a
    > way that will create some problem if you have inherited from it. But
    > this is based on an expectation I have about a class I haven't seen.


    Believe me, the class I'm talking about is the QTcpSocket, and
    Trolltech has nothing against inheritance about it :)

    I would like to say that what I'm talking about is an idea, a
    curiosity. All the issues I've explained can be worked out in many
    common ways. Don't feel like I'm saying "your idea is not right,
    doesn't work", I'm just talking with many smart guys about an
    interesting subject.

    Thank you all for your time.

    --
    Iacopo
    iakko, Jan 14, 2009
    #19
  20. On Jan 12, 5:02 pm, iakko <> wrote:
    > Hello everybody,
    > first of all, sorry if the question I'm about to ask have been already
    > answered, but after some hours spent bothering google, I did not work
    > it out.
    >
    > I have two classes:
    >
    > class Base
    > {
    > public:
    >         Base() { k = 0; };
    >         ~Base() {};
    >
    >         int k;
    >         void setK(int p) { k = p; };
    >         int getK() { return k; };
    >
    >         void myMethod() { /* Code here */ };
    >
    > };
    >
    > class Derived : public Base
    > {
    > public:
    >         Derived() : Base() { i = 0; };
    >         ~Derived() {};
    >
    >         int i;
    >         void setI(int p) { i = p; };
    >         int getI() { return i; };
    >
    >         void myCoolMethod() { /* Code here */ };
    >
    > };
    >
    > Suppose I need to work with the derived class because I have to
    > implement many methods and I cannot touch the Base class since it's a
    > Qt class.
    >
    > What I would like to do is find a way to "merge" an implementation of
    > a Derived class with another implementation of Base class, due to have
    > all the data for the Base class avaiable in the Derived class.


    No, it is not possible to merge two distict objects into one.
    The best option you have is to create your Derived object with a
    *copy* of the Base object as its Base-class part.
    The second-best option is to overwrite the Base-class sub-object with
    a copy of the original Base object.

    With both options implemented, your derived class would look like
    this:
    class Derived : public Base
    {
    public:
    Derived(const Base& other) : Base(other) { i = 0; };
    ~Derived() {};

    int i;
    void setI(int p) { i = p; };
    int getI() { return i; };

    void myCoolMethod() { /* Code here */ };

    Derived& operator=(const Base& other)
    {
    Base::eek:perator=(other);
    return *this;
    }
    Derived& operator=(const Derived& other)
    {
    Base::eek:perator=(other);
    i = other.i;
    return *this;
    }

    };


    The reason merging is impossible, is because all object in C++ must
    occupy a contiguous sequence of bytes as storage. And an object of a
    Derived class physically contains a sub-object of the Base class, so
    the bytes occupied by the Base-class sub-object must be located within
    the range of bytes occupied by the Derived-class object.

    As your external libray can not know about the additional memory
    requirements of a possible Derived class, it will not even try to set
    aside enough memory to be able to convert a Base-class object into a
    Derived-class object, so that option is also out of the question.


    >
    > --
    > Iacopo


    Bart v Ingen Schenau
    Bart van Ingen Schenau, Jan 14, 2009
    #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.
Similar Threads
  1. Karl Heinz Buchegger
    Replies:
    3
    Views:
    521
    Karl Heinz Buchegger
    Aug 6, 2003
  2. John Harrison
    Replies:
    0
    Views:
    482
    John Harrison
    Aug 6, 2003
  3. ali
    Replies:
    4
    Views:
    558
    David Harmon
    Mar 5, 2007
  4. Replies:
    1
    Views:
    383
    myork
    May 23, 2007
  5. Replies:
    1
    Views:
    371
    Victor Bazarov
    May 23, 2007
Loading...

Share This Page