Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > issue with scope

Reply
Thread Tools

issue with scope

 
 
Ken
Guest
Posts: n/a
 
      11-05-2005
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:, v3d:() and
the x used as an argument in the function?

 
Reply With Quote
 
 
 
 
Peter Steiner
Guest
Posts: n/a
 
      11-05-2005
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

 
Reply With Quote
 
 
 
 
Ken
Guest
Posts: n/a
 
      11-05-2005
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.

 
Reply With Quote
 
Kaz Kylheku
Guest
Posts: n/a
 
      11-05-2005
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:, v3d:() 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.

 
Reply With Quote
 
Ian
Guest
Posts: n/a
 
      11-05-2005
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
 
Reply With Quote
 
Greg Comeau
Guest
Posts: n/a
 
      11-05-2005
In article <(E-Mail Removed) .com>,
Peter Steiner <(E-Mail Removed)> 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?
 
Reply With Quote
 
Greg Comeau
Guest
Posts: n/a
 
      11-05-2005
In article <(E-Mail Removed) .com>,
Ken <(E-Mail Removed)> 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?
 
Reply With Quote
 
Peter_Julian
Guest
Posts: n/a
 
      11-06-2005

"Ken" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) oups.com...
| 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:, v3d:() 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:stream& operator<<( std: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
*/


 
Reply With Quote
 
Peter_Julian
Guest
Posts: n/a
 
      11-06-2005

"Kaz Kylheku" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) oups.com...
| 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:, v3d:() 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.
|


 
Reply With Quote
 
Greg
Guest
Posts: n/a
 
      11-06-2005

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:, v3d:() and
> the x used as an argument in the function?


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

Greg

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Lexical scope vs. dynamic scope Xah Lee Java 0 02-26-2009 10:08 AM
CSPEC issue: lossing scope (or incorrect scope) in cspec subroutine. balldarrens@gmail.com Perl Misc 0 02-05-2009 08:42 PM
Scope - do I need two identical classes, each with different scope? ann Java 13 09-13-2005 03:07 AM
How do namespace scope and class scope differ? Steven T. Hatton C++ 9 07-19-2005 06:07 PM
IMPORT STATIC; Why is "import static" file scope? Why not class scope? Paul Opal Java 12 10-10-2004 11:01 PM



Advertisments