The template i have is:
template <class T>
class Shape {
T val,val_new;
public:
Shape(T initval)
{
val=initval;
}
T get()
{
return val;
}
void set (T newval)
{
val_new = newval;
}
void copy()
{
val= val_new;
}
};
The class to use this template is :
#include <iostream>
#include<math.h>
using namespace std;
class Rectangle
{
private:
Shape<TwoPoint> val;
bool incr_called, decr_called, load_called;
TwoPoint newval;
public:
Rectangle(TwoPoint i)
: val (Shape<TwoPoint> (i)) {}
Shape<TwoPoint> read()
{
return val;
}
void load(TwoPoint n)
{
load_called=1;
newval=n;
}
void increment()
{
incr_called=1;
}
void decrement()
{
decr_called=1;
}
void init()
{
incr_called=0;
decr_called=0;
load_called=0;
}
void actions()
{
if (load_called)
val.set(new TwoPoint(newval));
if(incr_called && !decr_called)
val.set((new TwoPoint(val.get())).plus(1));
if(!incr_called && decr_called)
val.set((new TwoPoint(val.get())).plus(-1));
}
};
TwoPoint class is defined as:
class TwoPoint
{
int width;
int value;
public:
TwoPoint()
{
value=0;
width=0;
}
TwoPoint(int v, int w)
{
value=v;
width=w;
}
TwoPoint(const TwoPoint& t)
{
value= t.value;
width= t.width;
}
int getWidth()
{
return width;
}
int getValue()
{
return value;
}
TwoPoint & plus(int newval)
{
value+=newval;
return *this;
}
};
But there are errors:
In member function 'void Rectangle::actions()':
error: request for member 'plus' in '(((TwoPoint*)operator new(8u)), (((*<anonymous>)
<unknown operator> TwoPoint<T>::get() [with T=TwoPoint]()), <anonymous>))', which is of non-class type 'TwoPoint*'
There is another error:
In member function 'void Rectangle::actions()':
error: no pattern matching function for call to 'Shape<TwoPoint>::set(TwoPoint*)'
note: candidates are: void Shape<T>:: set<T> [with T=TwoPoint]
There are two more errors when i am doing similar operations in actions() due to same reason. Can somebody please explain these errors and how to improve them?
Is there any way in which i can make code more efficient?
Shape::settakes its argument by value, but you’re creating a value usingnewand passing a pointer. You should avoid usingnewunless you actually need a dynamic object; in which case, you need to make sure it’s deleted when you’ve finished with it.In this case, you just want to pass an object by value:
Dynamic allocation is usually less efficient than using automatic objects – fixing the error has also removed a source of inefficiency.
Shape::set, and the constructor, could take their arguments by reference, andShape::getcould return a reference, to avoid unnecessary copying; although in practice the compiler will probably avoid those copies anyway. Also, the constructor could use an initialiser list, to initialise the member(s) directly, rather than default-initialising them and the reassigning them. Code like this might be marginally more efficient in some cases:But in general, focus on making the code correct and readable, and on choosing efficient algorithms; only worry about small inefficiencies if they prove to be a bottleneck.