Request for member error

I am working on an OOP project and I am stuck on the following error:

|LINE: 28|error: request for member `clone' in `tleft->TimeValue::scale((1.0e+0 / dright))', which is of non-class type `TimeValue*'|

I created the scale function and tried to implement the virtual clone function to correct the error in the timevalue class.

It gets hung up here in line 28:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include "dividesnode.h"
#include "numvalue.h"
#include "errvalue.h"
#include "timevalue.h"

// Evaluate this expression
Value* DividesNode::evaluate(const SpreadSheet& s) const
{
  const Value* leftValue = left->evaluate(s);
  const Value* rightValue = right->evaluate(s);
  Value* result;

  if (leftValue->valueKind() == NumericValue::valueKindName()
      && rightValue->valueKind() == NumericValue::valueKindName())
    {
      double dleft =
	dynamic_cast<const NumericValue*>(leftValue)->getNumericValue();
      double dright =
	dynamic_cast<const NumericValue*>(rightValue)->getNumericValue();
      result = new NumericValue(dleft / dright);
    }
  else if (leftValue->valueKind() == TimeValue::valueKindName()
      && rightValue->valueKind() == NumericValue::valueKindName())
    {
      TimeValue* tleft = (TimeValue*)leftValue;
      double dright =
	dynamic_cast<const NumericValue*>(rightValue)->getNumericValue();
      return tleft->scale(1.0 / dright).clone();
    }
  else if (leftValue->valueKind() == TimeValue::valueKindName()
      && rightValue->valueKind() == TimeValue::valueKindName())
    {
      TimeValue* tleft = (TimeValue*)leftValue;
      TimeValue* tright = (TimeValue*)rightValue;
      double ratio = tleft->proportion(*tright);
      return new NumericValue (ratio);
    }
  else
    result = new ErrorValue();

  delete leftValue;
  delete rightValue;
  return result;
}


// Copy this expression (deep copy), altering any cell references
// by the indicated offsets except where the row or column is "fixed"
// by a preceding $. E.g., if e is  2*D4+C$2/$A$1, then
// e.copy(1,2) is 2*E6+D$2/$A$1, e.copy(-1,4) is 2*C8+B$2/$A$1
Expression* DividesNode::clone (int colOffset, int rowOffset) const
{
  return new DividesNode(left->clone(colOffset, rowOffset),
			 right->clone(colOffset, rowOffset));
}


Here is timevalue.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include "timevalue.h"

#include <sstream>
#include <iomanip>
#include <cstdio>

//
// Time values in the spreadsheet.
//


using namespace std;

const char* TimeValue::theValueKindName = "Time";

const char* TimeValue::valueKind() const
  // Indicates what kind of value this is. For any two values, v1 and v2,
  // v1.valueKind() == v2.valueKind() if and only if they are of the
  // same kind (e.g., two numeric values). The actual character string
  // pointed to by valueKind() may be anything, but should be set to
  // something descriptive as an aid in identification and debugging.
{
  return theValueKindName;
}

Value* TimeValue::clone() const
{
  return new TimeValue();
}

TimeValue* TimeValue::scale(scalar) const
{

    return new TimeValue(d,h,m,s);
}


Here is timevalue.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#ifndef TIMEVALUE_H
#define TIMEVALUE_H

#include "value.h"

//
// Numeric values in the spreadsheet.
//
class TimeValue: public Value
{
int d;
int h;
int m;
int s;
static const char* theValueKindName;

public:

TimeValue():d(0),h(0),m(0),s(0)  {}
TimeValue (int day, int hour, int min, int sec): d(day),h(hour),m(min),s(sec) {}

static const char* valueKindName()  {return theValueKindName;}

virtual const char* valueKind() const;

virtual Value* clone() const;

TimeValue* scale(double scalar) const;


};

#endif 


Here is value.h which I believe that line 28 is really trying to reach?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#ifndef VALUE_H
#define VALUE_H

#include <string>

//
// Represents a value that might be obtained for some spreadsheet cell
// when its formula was evaluated.
// 
// Values may come in many forms. At the very least, we can expect that
// our spreadsheet will support numeric and string values, and will
// probably need an "error" or "invalid" value type as well. Later we may 
// want to add addiitonal value kinds, such as currency or dates.
//
class Value
{
public:
  virtual ~Value() {}

  virtual const char* valueKind() const = 0;
  // Indicates what kind of value this is. For any two values, v1 and v2,
  // v1.valueKind() == v2.valueKind() if and only if they are of the
  // same kind (e.g., two numeric values). The actual character string
  // pointed to by valueKind() may be anything, but should be set to
  // something descriptive as an aid in identification and debugging.


  virtual std::string render (unsigned maxWidth) const = 0;
  // Produce a string denoting this value such that the
  // string's length() <= maxWidth (assuming maxWidth > 0)
  // If maxWidth==0, then the output string may be arbitrarily long.
  // This function is intended to supply the text for display in the
  // cells of a spreadsheet.


  virtual Value* clone() const = 0;
  // make a copy of this value. Typically implementd by a subclass S
  // as:   return new S(*this);

protected:
  virtual bool isEqual (const Value& v) const = 0;
  //pre: valueKind() == v.valueKind()
  //  Returns true iff this value is equal to v, using a comparison
  //  appropriate to the kind of value.

  friend bool operator== (const Value&, const Value&);
};

inline
bool operator== (const Value& left, const Value& right)
{
  return (left.valueKind() == right.valueKind())
    && left.isEqual(right);
}

#endif 
Because scale returnes a pointer to a TimeValue, shouldn't it be :
(I use brackets to make sure I get the precedence right).
That is use the -> pointer for access rather than a . (dot)?

return (tleft->scale(1.0 / dright))->clone();
Topic archived. No new replies allowed.