C++ design question

J

Jessica

Hi,

I have a design question. I am making a time series analysis tool.
Since I already use STL vector to represent time series, is there a
need to implement a class for the time series object? Right now I
just use

typedef vector<double>TS;

Is that enough? I feel that I am not taking advantage of the C++
encapsulation. But implementing the class seems redundant.. I'd
appreciate some insight! Thanks in advance!

Jessica
 
C

Cy Edmunds

Jessica said:
Hi,

I have a design question. I am making a time series analysis tool.
Since I already use STL vector to represent time series, is there a
need to implement a class for the time series object? Right now I
just use

typedef vector<double>TS;

Is that enough? I feel that I am not taking advantage of the C++
encapsulation. But implementing the class seems redundant.. I'd
appreciate some insight! Thanks in advance!

Jessica

I wouldn't say that "taking advantage of the C++ encapsulation" is an issue.
But as you develop your project it seems likely you will find more to say
about a time series than just the time values themselves. If so you will
wish you had started with a class like this:

class TimeSeries
{
public:
typedef double t_time;
typedef std::vector<double> t_series;
private:
t_series m_series;
// probably other stuff to be added here later
public:
TimeSeries() {}
template <typename ITER> TimeSeries(ITER first, ITER last) :
m_series(first, last) {}
const t_series &series() const {return m_series;}
t_series &series() {return m_series;}
// accessors for new stuff to be added here as needed
};

[untested code] As you can see, there isn't that much to it and if you
decide to add some other properties to TimeSeries you can do so without
breaking your code. If you diligently declare times as TimeSeries::t_time
and container references as TimeSeries::t_series you can change your mind
about those types later. You will have to use syntax such as:

TimeSeries::t_time t = my_ts.series().front();

rather than

TimeSeries::t_time t = my_ts.front();

Not so terrible, IMHO.
 
P

Phlip

Jessica said:
I have a design question. I am making a time series analysis tool.
Since I already use STL vector to represent time series, is there a
need to implement a class for the time series object? Right now I
just use

typedef vector<double>TS;

Is that enough? I feel that I am not taking advantage of the C++
encapsulation. But implementing the class seems redundant.. I'd
appreciate some insight! Thanks in advance!

Forget encapsulation.

(On modern projects, a given binary only grows so large before we use a pipe
or COM to plug it into a bigger app, so that's the encapsulation boundary.)

Focus on removing duplication.

If two clients do similar things to a vector of doubles, refactor them until
their code looks similar.

Then, replace the two similar procedures with a call to a new function,
containing those common lines.

The simplest place to put that common function is inside a class that also
contains TS.

Voila: Objects.
 
J

Jessica

Thank you all for your professional opinions. Now I look at this
language with a whole new perspective. As you can probably tell, I am
a student and haven't really been thinking about object-orientation
from a practical view. :) This is my first project in the real world,
and I am glad that I consulted with you pros first!

Jessica
 
J

Jessica

Hi,

I started implementing the wrapper class for vector<double> but I
ran into some trouble. Hope some of you can help me.

First of all, I was trying to over load the [] operator:

// operator overloading. _tsVal is a private member declared as
vector<Type>
Type& operator[](int its) const
{
return _tsVal.at(its);
}

But the compiler complains that I am trying to convert
std::allocator<_Ty>::value_type to double&. So I changed the return
type to vector<Type>&

Now it compiles, but I get stuck in trying to overload the +=
operator. In the client code I want to be able to do something like
this:

myClassObject += someDouble; or
someDouble += myClassObject

But if operator[] returns the reference to the vector, how can I get
the value of myClassObject? What do I pass in as the operand?

Perhaps I am doing something wrong. Please help. Thank you!

Jessica
 
J

Jessica

Hi,

Never mind my silly question. After thinking about it more
carefully, I realized that I've got the concept of operator
overloading all wrong. But can someone please tell me why

someDouble += myClassObject;

doesn't work if [] has higher precedence? Thanks.

Jessica

Hi,

I started implementing the wrapper class for vector<double> but I
ran into some trouble. Hope some of you can help me.

First of all, I was trying to over load the [] operator:

// operator overloading. _tsVal is a private member declared as
vector<Type>
Type& operator[](int its) const
{
return _tsVal.at(its);
}

But the compiler complains that I am trying to convert
std::allocator<_Ty>::value_type to double&. So I changed the return
type to vector<Type>&

Now it compiles, but I get stuck in trying to overload the +=
operator. In the client code I want to be able to do something like
this:

myClassObject += someDouble; or
someDouble += myClassObject

But if operator[] returns the reference to the vector, how can I get
the value of myClassObject? What do I pass in as the operand?

Perhaps I am doing something wrong. Please help. Thank you!

Jessica


Phlip said:
Forget encapsulation.

(On modern projects, a given binary only grows so large before we use a pipe
or COM to plug it into a bigger app, so that's the encapsulation boundary.)

Focus on removing duplication.

If two clients do similar things to a vector of doubles, refactor them until
their code looks similar.

Then, replace the two similar procedures with a call to a new function,
containing those common lines.

The simplest place to put that common function is inside a class that also
contains TS.

Voila: Objects.
 
V

Victor Bazarov

Jessica said:
Never mind my silly question. After thinking about it more
carefully, I realized that I've got the concept of operator
overloading all wrong. But can someone please tell me why

someDouble += myClassObject;

doesn't work if [] has higher precedence? Thanks.


Your question makes no sense, sorry. [] _always_ has higher
precedence, there can be no "if". And if whatever you wrote
doesn't work, how can anybody tell you why it doesn't work
without seeing what you actually wrote?

Victor
 
J

Jessica

Hi Cy,

Thanks! I didn't have a const return type on my const function:

(const) Type &operator [] (int) const;

Adding the "const" on this one, as well as adding another non-const
function, solved all the problems! And thanks for all the reasonings
behind it.

Jessica


p.s. Victor, sorry I didn't phrase the question well enough -- I was
questioning why the compiler complains about += in this statement,
SINCE [] has higher precedence:

a += b

I thought the compiler was complaining that I didn't overload the +=
operator, but apparently it was because I didn't implement []
overloading correctly, as Cy explained.



Cy Edmunds said:
Jessica said:
Hi,

I started implementing the wrapper class for vector<double> but I
ran into some trouble. Hope some of you can help me.

First of all, I was trying to over load the [] operator:

// operator overloading. _tsVal is a private member declared as
vector<Type>
Type& operator[](int its) const
{
return _tsVal.at(its);
}

When you declare the function to be "const" you are promising that the
function does not change the internal state of the object. So you can't
change _tsVal, for instance, and you can't call another function unless it
is also const. If you look at the code for <vector> I am sure you will see
that the "at" function has a const version which returns a const reference
and a non-const version which returns a non-const reference. When you wrote:

return _tsVal.at(its);

you were calling the const version of at() -- calling the non-const version
would violate const-correctness. Hence the return type was a const Type &
which you then tried to convert to a non-const Type &. I wasn't impressed
with the error message you got but that's life in template city.

It is usual for a const function to return only a const reference or const
pointer. You can write both in the same class:

Type &operator [] (int);
const Type &operator [] (int) const;

These are two different functions because they have different signatures
(the const declaration counts as part of the signature). I suggest you
implement both of these functions in your class and I think all will be
well.

BTW the practical implication of implementing both is that if your client
has a const object he can still use operator [] on the right hand side:

function yadda(const TimeSeries &ts)
{
double foo = ts[4]; // calls operator [] (int) const -- legal
ts[4] = 12.2; // calls operator [] (int) -- not legal
}

If he has a non-const object he can use operator [] on either side of the
assignment.

<snip>

Cy
 

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

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,120
Latest member
ShelaWalli
Top