Reputation: 129
Just doing a simple exercise where I'm translating ideas I learned from another language to C++.
I have an abstract class Number, which has two derived classes, PositiveNumber and NegativeNumber. Number has a static method that should create a new instance of either PositiveNumber or Negative number, depending on the sign of its input.
#include <iostream>
class Number
{
public:
protected:
int magnitude_;
public:
static Number* fromInt(int x)
{
if (x >= 0) { return new PositiveNumber(x); }
else { return new NegativeNumber(x); }
}
int getMagnitude() { return magnitude_; }
virtual void print() = 0;
};
class PositiveNumber: public Number
{
protected:
public:
PositiveNumber(int magnitude) { magnitude_ = magnitude; }
void print() { std::cout << magnitude_ << "\n"; }
};
class NegativeNumber: public Number
{
protected:
public:
NegativeNumber(int magnitude) { magnitude_ = magnitude; }
void print() { std::cout << "-" << magnitude_ << "\n"; }
};
int main (int argc, char* argv[])
{
Number* x = Number::fromInt(5);
x->print();
return 0;
}
I know that I need to tell Number that PositiveNumber and NegativeNumber exist, but I'm not sure how to do that. I tried adding
class PositiveNumber;
class NegativeNumber;
before Number's definition, but that wasn't enough, and resulted in:
use of undefined type 'PositiveNumber'
use of undefined type 'NegativeNumber'
I'm sure this has a simple answer, but I'm pretty new to debugging C++ stuff, so I'm pretty lost. Thanks for reading.
Upvotes: 1
Views: 196
Reputation: 595827
The definition of fromInt()
needs to know what constructors PositiveNumber
and NegativeNumber
have, so forward declarations are not enough. You need to break up the declaration and definition of Number::fromInt()
, and then you can move the definition underneath the declarations of PositiveNumber
and NegativeNumber
.
Also, don't forget to delete
the object that fromInt()
new
's. Which also means adding a virtual destructor to Number
so derived destructors can be called correctly from a base Number*
pointer.
Try this:
#include <iostream>
class Number
{
protected:
int magnitude_;
public:
static Number* fromInt(int x);
virtual ~Number() {}
int getMagnitude() { return magnitude_; }
virtual void print() = 0;
};
class PositiveNumber: public Number
{
public:
PositiveNumber(int magnitude) { magnitude_ = magnitude; }
void print() { std::cout << magnitude_ << "\n"; }
};
class NegativeNumber: public Number
{
public:
NegativeNumber(int magnitude) { magnitude_ = magnitude; }
void print() { std::cout << "-" << magnitude_ << "\n"; }
};
Number* Number::fromInt(int x)
{
if (x >= 0) { return new PositiveNumber(x); }
else { return new NegativeNumber(x); }
}
int main (int argc, char* argv[])
{
Number* x = Number::fromInt(5);
x->print();
delete x;
return 0;
}
Upvotes: 2