issue with scope

K

Ken

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?
 
P

Peter Steiner

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
 
K

Ken

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.
 
K

Kaz Kylheku

Ken said:
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.
 
I

Ian

Ken said:
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
 
G

Greg Comeau

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.
 
G

Greg Comeau

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.
 
P

Peter_Julian

| 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
*/
 
P

Peter_Julian

| 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.
|
 
G

Greg

Ken said:
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
 
K

Ken

Because my vectors require some operations... addition, subtraction,
dot and cross products, projection and length.
 
K

Ken

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.
 
I

Ian

Ken said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top