Picking const vs. non-const member functions upon a call

Discussion in 'C++' started by cheeser, Oct 6, 2003.

  1. cheeser

    cheeser Guest

    Hello all,

    Please see the question in the code below...

    Thanks!
    Dave


    #include <iostream>

    using namespace std;

    class foo
    {
    public:
    foo(int d) : data(d) {}
    void print() const {cout << "const" << endl;}
    void print() {cout << "non-const" << endl;}

    private:
    int data;
    };

    int main()
    {
    foo a(42);

    // The call below calls the non-const print();
    // I want the const print() to be called!
    // a.print();

    // Here's one way to do it. Is there a more elegant way?
    // Making a const is not within the scope of my question!
    static_cast<const foo>(a).print();

    return 0;
    }
     
    cheeser, Oct 6, 2003
    #1
    1. Advertising

  2. cheeser wrote:

    > #include <iostream>
    >
    > class foo {
    > private:
    > int data;
    > public:
    > foo(int d): data(d) { }
    > void print(void) const {std::cout << "const" << std::endl;}
    > void print(void) {std::cout << "non-const" << std::endl;}
    > };
    >
    > int main(int argc, char* argv[]) {
    > const foo a(42);
    > a.print();
    > return 0;
    > }
     
    E. Robert Tisdale, Oct 6, 2003
    #2
    1. Advertising

  3. cheeser

    Mike Wahler Guest

    "cheeser" <> wrote in message
    news:...
    >
    > Hello all,
    >
    > Please see the question in the code below...
    >
    > Thanks!
    > Dave
    >
    >
    > #include <iostream>
    >
    > using namespace std;
    >
    > class foo
    > {
    > public:
    > foo(int d) : data(d) {}
    > void print() const {cout << "const" << endl;}
    > void print() {cout << "non-const" << endl;}
    >
    > private:
    > int data;
    > };
    >
    > int main()
    > {
    > foo a(42);
    >
    > // The call below calls the non-const print();
    > // I want the const print() to be called!


    The invoke the function with a const object.

    const foo a(42);

    > // a.print();
    >
    > // Here's one way to do it. Is there a more elegant way?


    Define "elegant".

    > // Making a const is not within the scope of my question!


    You're asking about const member functions, so yes it is,
    whether you deny it or not. :)

    > static_cast<const foo>(a).print();
    >
    > return 0;
    > }


    What real specific problem are you trying to solve?

    -Mike
     
    Mike Wahler, Oct 7, 2003
    #3
  4. > Please see the question in the code below...
    >
    > Thanks!
    > Dave
    >
    >
    > #include <iostream>
    >
    > using namespace std;


    Are you sure you want that?

    > class foo
    > {
    > public:
    > foo(int d) : data(d) {}
    > void print() const {cout << "const" << endl;}


    This would be called with

    const foo f;
    f.print();

    > void print() {cout << "non-const" << endl;}


    And that would be called with

    foo f;
    f.print();

    > private:
    > int data;
    > };
    >
    > int main()
    > {
    > foo a(42);
    >
    > // The call below calls the non-const print();
    > // I want the const print() to be called!
    > // a.print();
    >
    > // Here's one way to do it. Is there a more elegant way?
    > // Making a const is not within the scope of my question!
    > static_cast<const foo>(a).print();


    Whether a const member function will be called or not depends
    on the constness of the object. Why do you want that? Perhaps
    we could find another way.


    Jonathan
     
    Jonathan Mcdougall, Oct 7, 2003
    #4
  5. cheeser

    cheeser Guest

    > > int main()
    > > {
    > > foo a(42);
    > >
    > > // The call below calls the non-const print();
    > > // I want the const print() to be called!
    > > // a.print();
    > >
    > > // Here's one way to do it. Is there a more elegant way?
    > > // Making a const is not within the scope of my question!
    > > static_cast<const foo>(a).print();

    >
    > Whether a const member function will be called or not depends
    > on the constness of the object. Why do you want that? Perhaps
    > we could find another way.


    Here's the original code again:

    #include <iostream>

    using namespace std;

    class foo
    {
    public:
    foo(int d) : data(d) {}
    void print() const {cout << "const" << endl;}
    void print() {cout << "non-const" << endl;}

    private:
    int data;
    };

    int main()
    {
    foo a(42);

    // The call below calls the non-const print();
    // I want the const print() to be called!
    // a.print();

    // Here's one way to do it. Is there a more elegant way?
    // Making a const is not within the scope of my question!
    static_cast<const foo>(a).print();

    return 0;
    }


    OK, let me take a stab again at articulating what I'm after. There are two
    member functions in class foo that I care about: print() and print() const.
    If I had a const foo, I would be restricted to calling only print() const.
    However, I don't have a const foo (it's the whole point of the problem;
    please don't change it to const or you'll be answering a question different
    than what I asked, and one that I know the answer too!). Therefore, it is
    *semantically* valid for me to call either print() or print() const. This
    can be verified by removing the non-const print(). In that case, the
    non-const foo object will correctly invoke print() cont.

    My question is nothing more than trying to verify that, other than with a
    cast to const foo, it is not *syntactically* possible for me to call print()
    const (even though it is *semantically* legal, as detailed above). In other
    words, I can't do this:

    a.print() cost;

    Hmmm, it just occurred to me that there may be a way with using a
    pointer-to-member, but that would be somewhat ugly too. I think I may have
    exhausted the possibilities, but I'm merely throwing this out to those more
    experienced than I for confirmation...
     
    cheeser, Oct 7, 2003
    #5
  6. cheeser

    Mike Wahler Guest

    "cheeser" <> wrote in message
    news:...
    > > > int main()
    > > > {
    > > > foo a(42);
    > > >
    > > > // The call below calls the non-const print();
    > > > // I want the const print() to be called!
    > > > // a.print();
    > > >
    > > > // Here's one way to do it. Is there a more elegant way?
    > > > // Making a const is not within the scope of my question!
    > > > static_cast<const foo>(a).print();

    > >
    > > Whether a const member function will be called or not depends
    > > on the constness of the object. Why do you want that? Perhaps
    > > we could find another way.

    >
    > Here's the original code again:
    >
    > #include <iostream>
    >
    > using namespace std;
    >
    > class foo
    > {
    > public:
    > foo(int d) : data(d) {}
    > void print() const {cout << "const" << endl;}
    > void print() {cout << "non-const" << endl;}
    >
    > private:
    > int data;
    > };
    >
    > int main()
    > {
    > foo a(42);
    >
    > // The call below calls the non-const print();
    > // I want the const print() to be called!
    > // a.print();
    >
    > // Here's one way to do it. Is there a more elegant way?
    > // Making a const is not within the scope of my question!
    > static_cast<const foo>(a).print();
    >
    > return 0;
    > }
    >
    >
    > OK, let me take a stab again at articulating what I'm after. There are

    two
    > member functions in class foo that I care about: print() and print()

    const.
    > If I had a const foo, I would be restricted to calling only print() const.
    > However, I don't have a const foo (it's the whole point of the problem;
    > please don't change it to const or you'll be answering a question

    different
    > than what I asked, and one that I know the answer too!). Therefore, it is
    > *semantically* valid for me to call either print() or print() const. This
    > can be verified by removing the non-const print(). In that case, the
    > non-const foo object will correctly invoke print() cont.
    >
    > My question is nothing more than trying to verify that, other than with a
    > cast to const foo, it is not *syntactically* possible for me to call

    print()
    > const (even though it is *semantically* legal, as detailed above). In

    other
    > words, I can't do this:
    >
    > a.print() cost;
    >
    > Hmmm, it just occurred to me that there may be a way with using a
    > pointer-to-member, but that would be somewhat ugly too. I think I may

    have
    > exhausted the possibilities, but I'm merely throwing this out to those

    more
    > experienced than I for confirmation...


    Since neither version of your 'print()' function modifies
    the object, there isn't really any reason to define a non-const
    'print()' function at all.

    Just remove the nonconst version, and the const version
    will be invoked for const or nonconst objects.

    -Mike
     
    Mike Wahler, Oct 7, 2003
    #6
  7. cheeser

    cheeser Guest

    > Just remove the nonconst version, and the const version
    > will be invoked for const or nonconst objects.
    >
    > -Mike


    That is correct, but it evades the whole point of the question! The question
    may as well not even be asked if I go with something that doesn't address
    the point of what I'm getting at!

    I think by now I could probably safely conclude that the answer to my
    question is that there's no way to do what I was asking about.

    Thanks,
    Dave
     
    cheeser, Oct 7, 2003
    #7
  8. cheeser

    Mike Wahler Guest

    "cheeser" <> wrote in message
    news:...
    > > Just remove the nonconst version, and the const version
    > > will be invoked for const or nonconst objects.
    > >
    > > -Mike

    >
    > That is correct, but it evades the whole point of the question!


    I still fail to see the point.

    >The question
    > may as well not even be asked if I go with something that doesn't address
    > the point of what I'm getting at!


    Which is?

    Are you asking if you can circumvent the design of C++?
    Yes, in many cases you can. Your casting example is how
    in this particular case.

    >
    > I think by now I could probably safely conclude that the answer to my
    > question is that there's no way to do what I was asking about.


    No, not without a cast. I think I have a much better question:
    *Why* do you want to do this?

    -Mike
     
    Mike Wahler, Oct 7, 2003
    #8
  9. > > Whether a const member function will be called or not depends
    > > on the constness of the object. Why do you want that? Perhaps
    > > we could find another way.

    >
    > Here's the original code again:


    <snipped again>

    > OK, let me take a stab again at articulating what I'm after.


    That is not what I asked. Your question has been answered, it
    is not possible to call a const member function from a non
    const object if it is overloaded with a non-const function,
    except with casting (which makes the object const, back to the
    starting point).

    My question was : why do you want that? Perhaps we could find
    another way. Post some real code with your real design with
    some real problems.


    Jonathan
     
    Jonathan Mcdougall, Oct 7, 2003
    #9
  10. cheeser

    cheeser Guest

    Mike, Jonathan and Robert,

    I merely wanted to verify that it is not possible (without undesirable casts
    or other things of that ilk) to invoke a const method from a non-const
    object if there is also a non-const method of the same name. I do not have
    a specific application at hand; I just wanted confirmation that my
    understnading that it can't be done is correct. You have provided that
    confirmation. For this I offer my thanks.

    A good evening to all,
    Dave
     
    cheeser, Oct 7, 2003
    #10
  11. cheeser

    John Carson Guest

    "cheeser" <> wrote in message
    news:
    > Mike, Jonathan and Robert,
    >
    > I merely wanted to verify that it is not possible (without
    > undesirable casts or other things of that ilk) to invoke a const
    > method from a non-const object if there is also a non-const method of
    > the same name. I do not have a specific application at hand; I just
    > wanted confirmation that my understnading that it can't be done is
    > correct. You have provided that confirmation. For this I offer my
    > thanks.
    >
    > A good evening to all,
    > Dave


    Same name yes, if the arguments can differ.

    class foo
    {
    public:
    foo(int d) : data(d) {}
    void print(int a=0) const {cout << "const" << endl;}
    void print() {cout << "non-const" << endl;}
    private:
    int data;
    };


    int main()
    {
    foo a(42);
    const foo b(43);

    a.print(); // non-const
    a.print(0); // const
    b.print(); // const
    return 0;
    }


    --
    John Carson
    1. To reply to email address, remove donald
    2. Don't reply to email address (post here instead)
     
    John Carson, Oct 7, 2003
    #11
  12. cheeser wrote:

    >
    > // The call below calls the non-const print();
    > // I want the const print() to be called!
    > // a.print();
    >
    > // Here's one way to do it. Is there a more elegant way?
    > // Making a const is not within the scope of my question!
    > static_cast<const foo>(a).print();
    >


    Here's an alternative, but I don't know if I'd consider it any more elegant:

    const foo &ca = a;
    ca.print();

    I believe that will do what you are asking.

    -Kevin
    --
    My email address is valid, but changes periodically.
    To contact me please use the address from a recent posting.
     
    Kevin Goodsell, Oct 7, 2003
    #12
  13. John Carson wrote:
    > "cheeser" <> wrote in message
    > news:
    >
    >>Mike, Jonathan and Robert,
    >>
    >>I merely wanted to verify that it is not possible (without
    >>undesirable casts or other things of that ilk) to invoke a const
    >>method from a non-const object if there is also a non-const method of
    >>the same name.

    >


    Here are a couple of other suggestions.

    class foo
    {
    public:
    foo(int d) : data(d) {}
    void print() const {cout << "const" << endl;}
    void print() {cout << "non-const" << endl;}
    void cprint() const { print(); }
    private:
    int data;
    };


    int main()
    {
    foo a(42);
    const foo & b(a);

    a.print(); // non-const
    b.print(); // const
    a.cprint(); // const
    return 0;
    }
     
    Gianni Mariani, Oct 7, 2003
    #13
  14. cheeser

    cheeser Guest

    "Kevin Goodsell" <> wrote in message
    news:iesgb.1133$...
    > cheeser wrote:
    >
    > >
    > > // The call below calls the non-const print();
    > > // I want the const print() to be called!
    > > // a.print();
    > >
    > > // Here's one way to do it. Is there a more elegant way?
    > > // Making a const is not within the scope of my question!
    > > static_cast<const foo>(a).print();
    > >

    >
    > Here's an alternative, but I don't know if I'd consider it any more

    elegant:
    >
    > const foo &ca = a;
    > ca.print();
    >
    > I believe that will do what you are asking.
    >
    > -Kevin
    > --
    > My email address is valid, but changes periodically.
    > To contact me please use the address from a recent posting.
    >


    Ahh, there it is! I had a feeling there had to be a way, but my mind just
    didn't get on the right track... Thanks man...
     
    cheeser, Oct 7, 2003
    #14
  15. cheeser

    Jerry Coffin Guest

    In article <>,
    says...

    [ ... ]

    > // The call below calls the non-const print();
    > // I want the const print() to be called!


    First of all, if you care much about this, it's probably a good clue
    that your design has major problems.

    > // a.print();
    >
    > // Here's one way to do it. Is there a more elegant way?
    > // Making a const is not within the scope of my question!
    > static_cast<const foo>(a).print();


    You have (at least) a few other choices, such as temporarily creating a
    reference to a const object, but they all come out the same. If a
    member function is overloaded based on const-ness, then the const
    overload should only be selected when you invoke it on (a reference or
    pointer to) a const object. Therefore, if you want to invoke the const
    member function, you need to treat the object as const, either through a
    cast (as you've already mentioned) or by referring to the object via a
    pointer or reference to const.

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.
     
    Jerry Coffin, Oct 7, 2003
    #15
  16. cheeser

    jeffc Guest

    "cheeser" <> wrote in message
    news:...
    >
    > #include <iostream>
    >
    > using namespace std;
    >
    > class foo
    > {
    > public:
    > foo(int d) : data(d) {}
    > void print() const {cout << "const" << endl;}
    > void print() {cout << "non-const" << endl;}
    >
    > private:
    > int data;
    > };
    >
    > int main()
    > {
    > foo a(42);
    >
    > // The call below calls the non-const print();
    > // I want the const print() to be called!
    > // a.print();
    >
    > // Here's one way to do it. Is there a more elegant way?
    > // Making a const is not within the scope of my question!
    > static_cast<const foo>(a).print();


    I don't know what the "scope" of your question is, but the obvious answer to
    me would be to define
    const foo a(42);
    But if that's not what you want, I think you should question if you really
    want a const and non-const version of the same function.
     
    jeffc, Oct 7, 2003
    #16
  17. cheeser

    jeffc Guest

    "Jonathan Mcdougall" <> wrote in message
    news:N6pgb.56335$...
    >
    > My question was : why do you want that? Perhaps we could find
    > another way. Post some real code with your real design with
    > some real problems.


    Why are you guys badgering this guy? He already said there is no point
    other than knowing whether or not it can be done.
     
    jeffc, Oct 7, 2003
    #17
  18. cheeser

    cpp_weenie Guest

    "Kevin Goodsell" <> wrote in message
    news:iesgb.1133$...
    > cheeser wrote:
    >
    > >
    > > // The call below calls the non-const print();
    > > // I want the const print() to be called!
    > > // a.print();
    > >
    > > // Here's one way to do it. Is there a more elegant way?
    > > // Making a const is not within the scope of my question!
    > > static_cast<const foo>(a).print();
    > >

    >
    > Here's an alternative, but I don't know if I'd consider it any more

    elegant:
    >
    > const foo &ca = a;
    > ca.print();
    >
    > I believe that will do what you are asking.
    >
    > -Kevin
    > --
    > My email address is valid, but changes periodically.
    > To contact me please use the address from a recent posting.
    >


    In fact, here's the full extent of possibilities:

    #include <iostream>

    using namespace std;

    class foo
    {
    public:
    void bar() {cout << "bar()" << endl;}
    void bar() const {cout << "bar() const " << endl;}
    void bar() volatile {cout << "bar() volatile" << endl;}
    void bar() const volatile {cout << "bar() const volatile" << endl;}
    };

    int main()
    {
    foo p;
    const foo &c = p;
    volatile foo &v = p;
    const volatile foo &cv = p;

    p.bar();
    c.bar();
    v.bar();
    cv.bar();

    return 0;
    }
     
    cpp_weenie, Oct 18, 2003
    #18
    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. David Scarlett
    Replies:
    3
    Views:
    860
    mlimber
    Feb 7, 2006
  2. fungus
    Replies:
    13
    Views:
    942
    fungus
    Oct 31, 2008
  3. flounder
    Replies:
    4
    Views:
    530
    flounder
    Apr 2, 2009
  4. Hicham Mouline
    Replies:
    0
    Views:
    454
    Hicham Mouline
    Apr 23, 2009
  5. Hicham Mouline
    Replies:
    1
    Views:
    439
    Michael DOUBEZ
    Apr 24, 2009
Loading...

Share This Page