Pure virtual accessors?

Discussion in 'C++' started by ardi, May 12, 2013.

  1. ardi

    ardi Guest

    Hi,

    In order to automate the document management in my applications (or at least minimizing the coding effort), I'm planning to base the document design on an abstract class which has a pure virtual getter, a pure virtual setter,a pure virtual function for saving the item into a file, a pure virtual function for reading it from the file, as well as any other helpful functions(such as automatically flagging the document as "dirty" when the value has changed by calling the setter).

    So, then I'd derive this abstract class into (for example) different classes for 16bit signed integers, 32bit unsigned integers, 32 bit floating point, 64 bit floating point, etc...

    The pure virtual functions for file I/O are trivial, and have no secrets.

    ....but... the pure virtual accessors are a different matter...

    I mean: how do you write a pure virtual getter if the return value has a different data type for each derived class?

    The getter for the 32 bit unsigned int will have a 32bit unsigned int as return value.

    The getter for the 32 bit float, will return a 32 bit float.

    How would I define both getters from a pure virtual getter? Is it possible?

    Thanks a lot for any suggestions, because this abstract data type class would ease a lot the coding effort in my applications!!

    ardi
    ardi, May 12, 2013
    #1
    1. Advertising

  2. ardi

    Stefan Ram Guest

    ardi <> writes:
    >I mean: how do you write a pure virtual getter if the return value has a different data type for each derived class?
    >The getter for the 32 bit unsigned int will have a 32bit unsigned int as return value.


    I can write this with /pointers/, but not with the actual values.

    struct base { };

    struct intval : base { int i; };
    struct doubleval : base { double x; };

    struct getter{ virtual base * get() const = 0; };

    struct intgetter : getter
    { intval * get() const override { return new intval; }; };

    struct doublegetter : getter
    { doubleval * get() const override { return new doubleval; }; };
    Stefan Ram, May 12, 2013
    #2
    1. Advertising

  3. On 12.05.13 17.55, ardi wrote:
    > I mean: how do you write a pure virtual getter if the return value has a different data type for each derived class?
    >
    > The getter for the 32 bit unsigned int will have a 32bit unsigned int as return value.
    >
    > The getter for the 32 bit float, will return a 32 bit float.
    >
    > How would I define both getters from a pure virtual getter? Is it possible?


    No. But it makes no sense anyway. If any part of the application uses
    the abstract base (without knowing about the actual implementation), it
    cannot extract a value of an unknown type, because it simply cannot have
    a target of the appropriate type.

    It seems that you want to mix design time polymorphism (here templates)
    with runtime polymorphism (virtual functions).

    More details about what you intend to do with the abstract getters would
    be helpful.


    Marcel
    Marcel Müller, May 14, 2013
    #3
  4. ardi

    Stefan Ram Guest

    Marcel Müller <> writes:
    >No. But it makes no sense anyway. If any part of the application uses
    >the abstract base (without knowing about the actual implementation), it
    >cannot extract a value of an unknown type


    Extracting values is for procedural programming,
    objects accept messages.

    #include <iostream>
    #include <ostream>

    struct val { virtual void print() const = 0; };

    struct intval : val
    { int i = 5; void print() const override{ ::std::cout << i << '\n'; }};

    struct doubleval : val
    { int x = 7; void print() const override{ ::std::cout << x << '\n'; }};

    struct getter{ virtual val * get() const = 0; };

    struct intgetter : getter
    { intval * get() const override { return new intval; }; };

    struct doublegetter : getter
    { doubleval * get() const override { return new doubleval; }; };

    int main()
    { getter * ig = new intgetter;
    getter * dg = new doublegetter;
    ig->get()->print();
    dg->get()->print(); }
    Stefan Ram, May 14, 2013
    #4
  5. ardi

    Haochen Xie Guest

    I guess boost.variant could help you? You can make the return type a
    variant, and that sounds like what you want.

    Or you could make your own using union holding pointers to various
    types, and provide different accessors for all the type it supports. An
    example could be:


    #include <string>
    #include <typeinfo>

    struct Variant {
    union {
    int *_i;
    float *_f;
    std::string *_str;
    };

    enum {
    vt_int, vt_float, vt_string
    } type;

    Variant(int x)
    : _i(new int(x)), type(vt_int) {}
    Variant(float x)
    : _f(new float(x)), type(vt_float) {}
    Variant(std::string x)
    : _str(new std::string(x)), type(vt_string) {}
    int &get_int() {
    if(type == vt_int)
    return *_i;
    else
    throw std::bad_cast();
    }
    float &get_float() {
    if(type == vt_float)
    return *_f;
    else
    throw std::bad_cast();
    }
    std::string &get_string() {
    if(type == vt_string)
    return *_str;
    else
    throw std::bad_cast();
    }
    };


    For testing program:


    #include <cassert>
    #include <iostream>
    using namespace std;

    int main() {
    Variant v1(17), v2((float)25.8), v3("I'm a string");

    assert(v1.type == Variant::vt_int);
    assert(v2.type == Variant::vt_float);
    assert(v3.type == Variant::vt_string);

    cout << v1.get_int() << endl;
    cout << v2.get_float() << endl;
    cout << v3.get_string() << endl;

    // The following line will throw a bad_cast exception
    cout << v1.get_string() << endl;
    }


    Virtual functions in a hierarchy tree must have *exactly* the same
    signature and return type if you want them to work correctly.
    Haochen Xie, May 15, 2013
    #5
  6. ardi

    ardi Guest

    On Tuesday, May 14, 2013 11:20:41 PM UTC+2, Marcel Müller wrote:
    > On 12.05.13 17.55, ardi wrote:
    >
    > > I mean: how do you write a pure virtual getter if the return value has a different data type for each derived class?

    >
    > >

    >
    > > The getter for the 32 bit unsigned int will have a 32bit unsigned int as return value.

    >
    > >

    >
    > > The getter for the 32 bit float, will return a 32 bit float.

    >
    > >

    >
    > > How would I define both getters from a pure virtual getter? Is it possible?

    >
    >
    >
    > No. But it makes no sense anyway. If any part of the application uses
    >
    > the abstract base (without knowing about the actual implementation), it
    >
    > cannot extract a value of an unknown type, because it simply cannot have
    >
    > a target of the appropriate type.
    >
    >
    >
    > It seems that you want to mix design time polymorphism (here templates)
    >
    > with runtime polymorphism (virtual functions).
    >
    >
    >
    > More details about what you intend to do with the abstract getters would
    >
    > be helpful.
    >
    >
    >
    >
    >
    > Marcel


    First, thanks a lot to all who replied. Your ideas were helpful.

    Second, you're right. My idea was wrong in the first place. What I'm doing is a class hierarchy where data and the document is managed as automatically as possible. Imagine you want to enhance a program adding a new member toa class. Typically this implies adding new logic in several places of the class even when the new member has a trivial management. My goal is that adding new members requires as few lines of code as possible.

    But, anyway, back to the point, I realized I don't want nor need "pure virtual getters" in such a system, so you were right in your comment.

    Thanks.

    ardi
    ardi, May 17, 2013
    #6
    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. IK
    Replies:
    2
    Views:
    597
    hemraj
    Jul 23, 2004
  2. John Goche
    Replies:
    10
    Views:
    726
    Marcus Kwok
    Dec 8, 2006
  3. Replies:
    7
    Views:
    581
    James Kanze
    May 2, 2007
  4. a
    Replies:
    7
    Views:
    356
    dasjotre
    Jun 28, 2007
  5. Austin McDonald

    Virtual instance-variable accessors

    Austin McDonald, Jun 10, 2004, in forum: Ruby
    Replies:
    2
    Views:
    82
    Austin McDonald
    Jun 11, 2004
Loading...

Share This Page