issue with scope

Discussion in 'C++' started by Ken, Nov 5, 2005.

  1. Ken

    Ken Guest

    I am familiar with C and Java, I would like to use a style that I have
    become accustomed to in Java with C++ but each time I do this I have
    name conflict. In the past I have just worked around it by using
    different names can anyone tell me how to get the following to work:

    I want to have a class named v3d (vector 3d), it has the following
    private instance variables...
    float x, y, z;

    It has the following public get and set methods:
    //set methods
    void x(float x);
    void y(float y);
    void z(float z);
    //get methods
    float x(void);
    float y(void);
    flaot z(void);

    The code in a set method...
    void x(float x){
    this->x = x;
    }

    The code in a get method...
    float x(void){
    return x;
    }

    Why does my compiler seem to have an issue with v3d::x, v3d::x() and
    the x used as an argument in the function?
     
    Ken, Nov 5, 2005
    #1
    1. Advertising

  2. it is not possible to declare two identifiers of differing type in the
    same scope in c++. it is a feature of the java grammar to recognize
    that you want to declare both a function and a variable, c++ does not
    support this.

    the function

    void x(float x){
    this->x = x;
    }

    should work properly if you would rename the function. the argument x
    shadows the member variable x in this case, thus the assignment works.

    -- peter
     
    Peter Steiner, Nov 5, 2005
    #2
    1. Advertising

  3. Ken

    Ken Guest

    If this is the case I am a bit disappointed. In the past I have either
    added the prefix 'its' onto the instance variables a suggestion from
    Jesse Liberty. Such as itsx, itsy, itsz or prefixed the member names
    with get and set... I like not having the get/set prefix on vector
    members because it will add a lot of typing.

    Thank you peter.
     
    Ken, Nov 5, 2005
    #3
  4. Ken

    Kaz Kylheku Guest

    Ken wrote:
    > I am familiar with C and Java, I would like to use a style that I have
    > become accustomed to in Java with C++ but each time I do this I have
    > name conflict.


    Well, then you just have to learn to write C++ the way C++ programmers
    do it and not try to write Java in C++.

    I'm familiar with Common Lisp, and everything else looks like crap.

    I suck it up!


    In the past I have just worked around it by using
    > different names can anyone tell me how to get the following to work:
    >
    > I want to have a class named v3d (vector 3d), it has the following
    > private instance variables...
    > float x, y, z;
    >
    > It has the following public get and set methods:
    > //set methods
    > void x(float x);
    > void y(float y);
    > void z(float z);
    > //get methods
    > float x(void);
    > float y(void);
    > flaot z(void);


    There is a roundabout way to do something better. Instead of using the
    float type directly, you can create a template class. Instances of that
    class behave like objects of the template argument type. they
    automatically convert to the type, and you can assign that type to
    them.

    But the template class has two additional parameters: namely, pointers
    to member functions to get and set the value. The template also takes a
    pointer to the object as a parameter, so it has an object to invoke
    these functions against.

    Use of this "SmartMember" template class might look like this:

    class MyClass {
    public:
    SmartMember<MyClass, int> x;
    public:
    MyClass() : x(this, &MyClass::get_x, &MyClass::set_x) { }
    private:
    int get_x();
    void set_x(const int &);
    };

    The SmartMember<int> object x stores a pointer to the MyClass instance,
    and pointers to two member functions for setting and getting. It has
    overloaded operators to do the magic. You can assign int values to x,
    or values that can implicitly convert to int. These values get passed
    to the set_x() function. You can also explicitly convert x to int,
    which will also happen implicitly in many contexts, like function
    argument expressions.

    MyClass obj;

    obj.x = 3; // calls obj.set_x(3);
    int y = obj.x; // calls obj.get_x();

    I will leave SmartMember<int> as an exercise for the reader. It's
    pretty easy. It goes something like this:

    template <class CLASS, class TYPE>
    class SmartMember {
    private:
    void (CLASS::* set_func)(const TYPE &);
    TYPE (CLASS::* get_func)();
    CLASS *obj;
    public:
    SmartMember(CLASS *o, void (CLASS::* sf)(const TYPE &), TYPE
    (CLASS::*gf)())
    : set_func(sf), get_func(gf), obj(o) { }
    SmartMember &operator = (const TYPE &rhs) { (obj->*set_func)(rhs);
    return *this; }

    // ... et cetera
    };

    It would be nice if the get_func and set_func could be made into
    template parameters instead, which would cut down the size of object.

    > The code in a get method...
    > float x(void){

    ^^^^^

    (void) is obsolete syntax for C compatibility. C compatibility is
    irrelevant when you are writing a C++ class member function, since you
    will never successfully get that through a C compiler.

    In C++, you write ().

    > return x;
    > }
    >
    > Why does my compiler seem to have an issue with v3d::x, v3d::x() and
    > the x used as an argument in the function?


    You can't overload a data member and a function member. You can
    overload functions only. So basically you have to rename your x. A
    member called m_x will happily coexist with a x() and x(float)
    function.

    But it's still ugly that it's a function: the language ought to be able
    to abstract accesses to what looks like a property x of the object. The
    user of the class shouldn't care whether x is a simple data member, or
    whether accesses to x are actually function calls that perform
    computation.

    The SmartMember template thing is a way to do that.
     
    Kaz Kylheku, Nov 5, 2005
    #4
  5. Ken

    Ian Guest

    Ken wrote:
    > I am familiar with C and Java, I would like to use a style that I have
    > become accustomed to in Java with C++ but each time I do this I have
    > name conflict. In the past I have just worked around it by using
    > different names can anyone tell me how to get the following to work:
    >
    > I want to have a class named v3d (vector 3d), it has the following
    > private instance variables...
    > float x, y, z;
    >

    for a simple container like this where you want to directly access the
    data members, why not simply use:

    struct v3d
    {
    double x;
    double y;
    double z;
    };

    Ian
     
    Ian, Nov 5, 2005
    #5
  6. Ken

    Greg Comeau Guest

    In article <>,
    Peter Steiner <> wrote:
    >it is not possible to declare two identifiers of differing type in the
    >same scope in c++.


    That's not always so...

    > it is a feature of the java grammar to recognize
    >that you want to declare both a function and a variable, c++ does not
    >support this.


    ....although this is.
    --
    Greg Comeau / Celebrating 20 years of Comeauity!
    Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
    World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
    Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
     
    Greg Comeau, Nov 5, 2005
    #6
  7. Ken

    Greg Comeau Guest

    In article <>,
    Ken <> wrote:
    >If this is the case I am a bit disappointed. In the past I have either
    >added the prefix 'its' onto the instance variables a suggestion from
    >Jesse Liberty. Such as itsx, itsy, itsz or prefixed the member names
    >with get and set... I like not having the get/set prefix on vector
    >members because it will add a lot of typing.


    This makes me wonder if there is not too much going on too low level
    about setting members?

    Also, a problem with something like its is what you've shown:
    itsy. That would mean something small to me.
    --
    Greg Comeau / Celebrating 20 years of Comeauity!
    Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
    World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
    Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
     
    Greg Comeau, Nov 5, 2005
    #7
  8. Ken

    Peter_Julian Guest

    "Ken" <> wrote in message
    news:...
    | I am familiar with C and Java, I would like to use a style that I have
    | become accustomed to in Java with C++ but each time I do this I have
    | name conflict. In the past I have just worked around it by using
    | different names can anyone tell me how to get the following to work:
    |
    | I want to have a class named v3d (vector 3d), it has the following
    | private instance variables...
    | float x, y, z;
    |
    | It has the following public get and set methods:
    | //set methods
    | void x(float x);
    | void y(float y);
    | void z(float z);
    | //get methods
    | float x(void);
    | float y(void);
    | flaot z(void);
    |
    | The code in a set method...
    | void x(float x){
    | this->x = x;
    | }
    |
    | The code in a get method...
    | float x(void){
    | return x;
    | }
    |
    | Why does my compiler seem to have an issue with v3d::x, v3d::x() and
    | the x used as an argument in the function?

    You may think the issue you raise is a weakness in the language, but
    its actually one of its powerful features. Ambiguity from the user's
    perspective is not allowed. It grately enhances the code's readability.
    This is specially true since you have the benefit of initialization
    lists in C++. Something those other languages would *love* to have.

    class N
    {
    int m_n;
    public:
    N() : m_n(0) { }
    N( int n ) : m_n(n) { }
    ~N() { }
    };

    N n(3);

    imagine a class that looks like this:

    #include <iostream>
    #include <ostream>

    template< typename T >
    class V3d
    {
    T x;
    T y;
    T z;
    public:
    V3d(T tx, T ty, T tz) : x(tx), y(ty), z(tz) { }
    ~V3d() { }
    void set(T tx, T ty, T tz)
    {
    x = tx;
    y = ty;
    z = tz;
    }
    friend std::eek:stream& operator<<( std::eek:stream& os, V3d< T >& t )
    {
    os << t.x << ", ";
    os << t.y << ", ";
    os << t.z << "\n";
    return os;
    }
    };

    int main()
    {
    V3d<int> n3d( 0, 1, 2 );
    std::cout << n3d;
    n3d.set( 3, 4, 5 );
    std::cout << n3d;

    V3d<double> d3d( 0.0, 1.1, 2.2 );
    std::cout << d3d;

    V3d<char> c3d( 'a', 'b', 'c' );
    std::cout << c3d;

    return 0;
    }

    /*
    0, 1, 2
    3, 4, 5
    0, 1.1, 2.2
    a, b, c
    */
     
    Peter_Julian, Nov 6, 2005
    #8
  9. Ken

    Peter_Julian Guest

    "Kaz Kylheku" <> wrote in message
    news:...
    | Ken wrote:
    | > I am familiar with C and Java, I would like to use a style that I
    have
    | > become accustomed to in Java with C++ but each time I do this I have
    | > name conflict.
    |
    | Well, then you just have to learn to write C++ the way C++ programmers
    | do it and not try to write Java in C++.
    |
    | I'm familiar with Common Lisp, and everything else looks like crap.
    |
    | I suck it up!
    |
    |
    | In the past I have just worked around it by using
    | > different names can anyone tell me how to get the following to work:
    | >
    | > I want to have a class named v3d (vector 3d), it has the following
    | > private instance variables...
    | > float x, y, z;
    | >
    | > It has the following public get and set methods:
    | > //set methods
    | > void x(float x);
    | > void y(float y);
    | > void z(float z);
    | > //get methods
    | > float x(void);
    | > float y(void);
    | > flaot z(void);
    |
    | There is a roundabout way to do something better. Instead of using the
    | float type directly, you can create a template class. Instances of
    that
    | class behave like objects of the template argument type. they
    | automatically convert to the type, and you can assign that type to
    | them.
    |
    | But the template class has two additional parameters: namely, pointers
    | to member functions to get and set the value. The template also takes
    a
    | pointer to the object as a parameter, so it has an object to invoke
    | these functions against.
    |
    | Use of this "SmartMember" template class might look like this:
    |
    | class MyClass {
    | public:
    | SmartMember<MyClass, int> x;
    | public:
    | MyClass() : x(this, &MyClass::get_x, &MyClass::set_x) { }
    | private:
    | int get_x();

    int get_x() const;

    | void set_x(const int &);
    | };
    |
    | The SmartMember<int> object x stores a pointer to the MyClass
    instance,
    | and pointers to two member functions for setting and getting. It has
    | overloaded operators to do the magic. You can assign int values to x,
    | or values that can implicitly convert to int. These values get passed
    | to the set_x() function. You can also explicitly convert x to int,
    | which will also happen implicitly in many contexts, like function
    | argument expressions.
    |
    | MyClass obj;
    |
    | obj.x = 3; // calls obj.set_x(3);
    | int y = obj.x; // calls obj.get_x();
    |
    | I will leave SmartMember<int> as an exercise for the reader. It's
    | pretty easy. It goes something like this:
    |
    | template <class CLASS, class TYPE>
    | class SmartMember {
    | private:
    | void (CLASS::* set_func)(const TYPE &);
    | TYPE (CLASS::* get_func)();
    | CLASS *obj;
    | public:
    | SmartMember(CLASS *o, void (CLASS::* sf)(const TYPE &), TYPE
    | (CLASS::*gf)())
    | : set_func(sf), get_func(gf), obj(o) { }
    | SmartMember &operator = (const TYPE &rhs) { (obj->*set_func)(rhs);
    | return *this; }
    |
    | // ... et cetera
    | };
    |
    | It would be nice if the get_func and set_func could be made into
    | template parameters instead, which would cut down the size of object.
    |
    | > The code in a get method...
    | > float x(void){
    | ^^^^^
    |
    | (void) is obsolete syntax for C compatibility. C compatibility is
    | irrelevant when you are writing a C++ class member function, since you
    | will never successfully get that through a C compiler.
    |
    | In C++, you write ().
    |
    | > return x;
    | > }
    | >
    | > Why does my compiler seem to have an issue with v3d::x, v3d::x() and
    | > the x used as an argument in the function?
    |
    | You can't overload a data member and a function member. You can
    | overload functions only. So basically you have to rename your x. A
    | member called m_x will happily coexist with a x() and x(float)
    | function.
    |
    | But it's still ugly that it's a function: the language ought to be
    able
    | to abstract accesses to what looks like a property x of the object.
    The
    | user of the class shouldn't care whether x is a simple data member, or
    | whether accesses to x are actually function calls that perform
    | computation.
    |
    | The SmartMember template thing is a way to do that.
    |
     
    Peter_Julian, Nov 6, 2005
    #9
  10. Ken

    Greg Guest

    Ken wrote:
    > I am familiar with C and Java, I would like to use a style that I have
    > become accustomed to in Java with C++ but each time I do this I have
    > name conflict. In the past I have just worked around it by using
    > different names can anyone tell me how to get the following to work:
    >
    > I want to have a class named v3d (vector 3d), it has the following
    > private instance variables...
    > float x, y, z;
    >
    > It has the following public get and set methods:
    > //set methods
    > void x(float x);
    > void y(float y);
    > void z(float z);
    > //get methods
    > float x(void);
    > float y(void);
    > flaot z(void);
    >
    > The code in a set method...
    > void x(float x){
    > this->x = x;
    > }
    >
    > The code in a get method...
    > float x(void){
    > return x;
    > }
    >
    > Why does my compiler seem to have an issue with v3d::x, v3d::x() and
    > the x used as an argument in the function?


    Why not just name the member variables x_, y_ and z_?

    Greg
     
    Greg, Nov 6, 2005
    #10
  11. Ken

    Ken Guest

    Because my vectors require some operations... addition, subtraction,
    dot and cross products, projection and length.
     
    Ken, Nov 6, 2005
    #11
  12. Ken

    Ken Guest

    I know I could have done it but I wanted to know if I was doing
    something wrong and there was some magic way to make it work.
     
    Ken, Nov 6, 2005
    #12
  13. Ken

    Ian Guest

    Ken wrote:
    > Because my vectors require some operations... addition, subtraction,
    > dot and cross products, projection and length.
    >

    So? Add them to the simple struct. If you are providing a full set of
    accessors, why complicate things with private data members?

    Also, please quote, this reply made no sense out of context.

    Ian
     
    Ian, Nov 6, 2005
    #13
    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. Paul Opal
    Replies:
    12
    Views:
    961
    Paul Opal
    Oct 11, 2004
  2. ann
    Replies:
    13
    Views:
    672
    Patricia Shanahan
    Sep 13, 2005
  3. Steven T. Hatton
    Replies:
    9
    Views:
    490
  4. Xah Lee
    Replies:
    0
    Views:
    2,249
    Xah Lee
    Feb 26, 2009
  5. Replies:
    0
    Views:
    167
Loading...

Share This Page