Reputation: 27
In Java, we can declare an interface variable without instantiation. This can help us deal with some abstract concepts. In the following Java example, I defined an interface UShape
and two UShape
classes, Rectangle
and Triangle
. In the test class bucket, I am able to define a private interface variable called myshape
and do things with this variable.
interface UShape {
void setwidth(int i);
void setheight(int i);
int getarea();
}
class Rectangle implements UShape{
private int w, h;
@Override
public void setwidth(int i) {
this.w = i;
}
@Override
public void setheight(int i) {
this.h = i;
}
@Override
public int getarea() {
return this.w * this.h;
}
}
class Triangle implements UShape{
private int w, h;
@Override
public void setwidth(int i) {
this.w = i;
}
@Override
public void setheight(int i) {
this.h = i;
}
@Override
public int getarea() {
return this.w * this.h / 2;
}
}
class bucket{
private UShape myshape;
//do something with myshape
public void defineShape(int i){
if (i == 1){
myshape = new Rectangle();
myshape.setwidth(5);
myshape.setheight(5);
}
}
public void printArea(){
System.out.println(myshape.getarea());
}
}
public class TestShape {
public static void main(String[] args){
bucket b = new bucket();
b.defineShape(1);
b.printArea();
}
}
My question now is, in C++, how can we implement this program? I've checked and found that abstract class in C++ cannot be used to declare variables like UShape myshape
. Can we use other methods to implement a class like bucket with an interface variable?
Upvotes: 0
Views: 151
Reputation: 55760
Maybe I misunderstood your question but there is no reason why you couldn't declare a private member of the abstract class type. The following should be similar to your Java example:
class UShape {
public:
virtual void setWidth (int w) =0;
virtual void setHeight (int h) =0;
virtual int getArea() =0;
virtual ~UShape() =0;
};
class Rectangle: public UShape {
private:
int width;
int height;
public:
void setWidth (int w) { this.width = w; }
void setHeight (int h) { this.height = h; }
int getArea (void) { return (width * height); }
};
class Triangle: public UShape {
private:
int width;
int height;
public:
void setWidth (int w) { this.width = w; }
void setHeight (int h) { this.height = h; }
int getArea (void) { return (width * height) / 2; }
};
class bucket{
private:
std::unique_ptr<UShape> myshape;
public:
//do something with myshape
void defineShape(int i){
if (i == 1){
myshape = std::make_unique<Rectangle>();
myshape->setWidth(5);
myshape->setHeight(5);
}
}
void printArea(){
cout << myshape ? myshape->getArea() : 0;
}
}
int main () {
bucket b();
b.defineShape(1);
b.printArea();
}
Upvotes: 3
Reputation: 21
I am going to use the same idea as Mike's but instead use C++11 and C++14 primitives for memory management ie. cleanup the memory allocated to the pointers without explicitly calling delete operator.
class UShape {
public:
virtual void setWidth (int w) =0;
virtual void setHeight (int h) =0;
virtual int getArea() =0;
};
class Rectangle: public UShape {
private:
int width;
int height;
public:
void setWidth (int w) { this.width = w; }
void setHeight (int h) { this.height = h; }
int getArea (void) { return (width * height); }
};
class Triangle: public UShape {
private:
int width;
int height;
public:
void setWidth (int w) { this.width = w; }
void setHeight (int h) { this.height = h; }
int getArea (void) { return (width * height) / 2; }
};
class bucket{
private:
std::unique_ptr<UShape> myshape; //c++11
public:
//do something with myshape
void defineShape(int i){
if (i == 1){
myshape = std::make_unique<Rectangle>(); //C++14
myshape->setWidth(5);
myshape->setHeight(5);
}
}
void printArea(){
cout << myshape->getArea();
}
}
int main () {
std::unique_ptr<bucket> b(new bucket()); //c++11
b->defineShape(1);
b->printArea();
}
Upvotes: 1
Reputation: 41331
In C++ you have to use pointers to base class, or better, smart pointers like shared_ptr
or unique_ptr
:
class bucket{
private:
std::unique_ptr<UShape> myshape;
public:
//do something with myshape
void defineShape(int i){
if (i == 1){
myshape = std::make_unique<Rectangle>();
myshape->setwidth(5);
myshape->setHeight(5);
}
}
void printArea(){
std::cout << myshape->getarea() << std::endl;
}
};
int main() {
bucket b;
b.defineShape(1);
b.printArea();
}
In some scenarios references are also helpful:
Rectangle r;
UShape& shape = r;
std::cout << shape.getarea() << std::endl;
Upvotes: 0