“
定义一个如下所示的CNumber类,并以其为基类派生出素数类CPrimeNumber,完全平方数类CCompleteSquareNumber和回文数类CPalindromeNumber。
class CNumber
{
protected:
char *p_type; // points to the text stating type of the number
public:
CNumber(char *p_number_type);
void print() { }
void printYes() { cout < < "It is a " < < p_type < < endl; }
void printNo() { cout < < "It is not a " < < p_type < < endl; }
virtual ~CNumber() { delete [] p_type; }
};
class CPrimeNumber : public CNumber
{
protected:
long n;
public:
CPrimeNumber(long n_val);
void print();
~CPrimeNumber() { }
};
class CCompleteSquareNumber : public CNumber
{
protected:
long n;
public:
CCompleteSquareNumber(long n_val);
void print();
~CCompleteSquareNumber() { }
};
class CPalindromeNumber : public CNumber
{
protected:
long n;
public:
CPalindromeNumber(long n_val)
void print();
~CPalindromeNumber() { }
};
void CPalindromeNumber::print()
{
long n1, sum=0;
int t;
n1 = n*n;
while (n1 != 0)
{
t = n1%10;
sum = sum*10 + t;
n1 = n1/10;
}
if (sum == n*n)
printYes();
else
printNo();
}
为了能实现如下例图所示的输出结果,应该怎样编写各个类其余各成员函数,并完成主函数的实现。
Enter a number <0 to exit>:13
Enter the type of number you want to check:
1.Prime number
2.Complete aquare number
3.Palindrome number
1
It is a Prime number
Enter a number <0 to exit>:16
Enter the type of number you want to check:
1.Prime number
2.Complete aquare number
3.Palindrome number
2
It is a Complete aquare number
Enter a number <0 to exit>:11
Enter the type of number you want to check:
1.Prime number
2.Complete aquare number
3.Palindrome number
3
It is a Palindrome number
Enter a number <0 to exit>:0
Press any key to continue
”
= = = = = = = = = = = = = = = = = = = = = = = = = = = = =
上文为网友的提问,其中“aquare”疑为“Square”之笔误。
这位朋友给出的部分实现代码,很是值得商榷,比如在类Cnumber中:
1. char *p_type;根本没有必要;
2. 下面3个函数如果都需要的话,将其设为虚函数更为恰当。
void print() { }
void printYes() { cout < < "It is a " < < p_type < < endl; }
void printNo() { cout < < "It is not a " < < p_type < < endl; }
还有,根据一般的规则,如果在类的定义出实现相关函数,最好使用如下的方式:
inline void printYes() { cout < < "It is a " < < p_type < < endl; }
…等等。
这个问题的实现完全可以不用所谓的设计模式,在下面的代码中,纯粹是为了顺便说明Factory Method这个设计模式的用法而引入了Factory Method模式,在这里,使用设计模式会增加很多代码。但这并不是说,设计模式不重要,事实上,设计模式是非常重要的。
代码如下:
// 抽象基类CNnumber
#include <math.h>
#include <iostream>
using namespace std;
class CNumber
{
public:
CNumber();
virtual void print() = 0; // 纯虚函数
virtual ~CNumber();
};
// 基类CNnumber的实现
CNumber::CNumber()
{
}
CNumber::~CNumber()
{
}
// 派生类CPrimeNumber
class CPrimeNumber : public CNumber
{
private:
long n;
public:
CPrimeNumber();
CPrimeNumber(long n);
void print();
virtual ~CPrimeNumber();
};
// 派生类CPrimeNumber的实现
CPrimeNumber::CPrimeNumber()
{
}
CPrimeNumber::CPrimeNumber(long n)
{
this->n = n;
}
void CPrimeNumber::print() // 重写基类的print,在此判断n是否为素数
{
int i;
int k;
k = sqrt((double)n);
for(i = 2; i <= k; i++)
{
if(n%i == 0) break;
}
if(i > k)
{
cout << n << " is a prime number" << endl;
}
else
{
cout << n << " isn't a prime number" << endl;
}
return;
}
CPrimeNumber::~CPrimeNumber()
{
}
// 派生类CCompleteSquareNumber
class CCompleteSquareNumber : public CNumber
{
private:
long n;
public:
CCompleteSquareNumber();
CCompleteSquareNumber(long n);
void print();
virtual ~CCompleteSquareNumber();
};
// 派生类CCompleteSquareNumber的实现
CCompleteSquareNumber::CCompleteSquareNumber()
{
}
CCompleteSquareNumber::CCompleteSquareNumber(long n)
{
this->n = n;
}
void CCompleteSquareNumber::print() // 重写基类的print,在此判断n是否为完全平方数
{
int k = sqrt((double)n);
if(n == k * k)
{
cout << n << " is a complete square number." << endl;
}
else
{
cout << n << " isn't a complete square number." << endl;
}
return;
}
CCompleteSquareNumber::~CCompleteSquareNumber()
{
}
// 派生类CPalindromeNumber
class CPalindromeNumber : public CNumber
{
protected:
long n;
public:
CPalindromeNumber();
CPalindromeNumber(long n);
void print();
virtual ~CPalindromeNumber();
};
// 派生类CPalindromeNumber的实现
CPalindromeNumber::CPalindromeNumber()
{
}
CPalindromeNumber::CPalindromeNumber(long n)
{
this->n = n;
}
void CPalindromeNumber::print() // 重写基类的print,在此判断n是否为回文数
{
int k;
int length;
char str[11];
itoa(n, str, 10);
length = strlen(str);
k = length / 2;
for(int i = 0; i < k; i++)
{
if(str[i] == str[length - i - 1])
{
continue;
}
else
{
cout << n << " isn't a palindrome number." << endl;
return;
}
}
cout << n << " is a palindrome number." << endl;
return;
}
CPalindromeNumber::~CPalindromeNumber()
{
}
// 抽象工厂类NumberFactory
class CNumberFactory
{
public:
CNumberFactory();
virtual ~CNumberFactory();
virtual CNumber* create(long number) = 0; // 这就是所谓的Factory Metho,即工厂方法
};
CNumberFactory::CNumberFactory()
{
}
CNumberFactory::~CNumberFactory()
{
}
// 具体工厂类CPrimeNumberFactory
class CPrimeNumberFactory : public CNumberFactory
{
protected:
CNumber* cnum;
public:
inline CPrimeNumberFactory()
{
cnum = NULL;
}
CNumber* create(long number); // 这就是所谓的Factory Metho,即工厂方法
virtual inline ~CPrimeNumberFactory()
{
if(cnum != NULL)
{
delete cnum;
cnum = NULL;
}
}
};
CNumber* CPrimeNumberFactory::create(long number)
{
cnum = new CPrimeNumber(number);
return cnum;
}
// 具体工厂类CPalindromeNumberFactory
class CCompleteSquareNumberFactory : public CNumberFactory
{
protected:
CNumber* cnum;
public:
inline CCompleteSquareNumberFactory()
{
cnum = NULL;
}
CNumber* create(long number); // 这就是所谓的Factory Metho,即工厂方法
virtual inline ~CCompleteSquareNumberFactory()
{
if(cnum != NULL)
{
delete cnum;
cnum = NULL;
}
}
};
CNumber* CCompleteSquareNumberFactory::create(long number)
{
cnum = new CCompleteSquareNumber(number);
return cnum;
}
// 具体工厂类CPalindromeNumberFactory
class CPalindromeNumberFactory : public CNumberFactory
{
protected:
CNumber* cnum;
public:
inline CPalindromeNumberFactory()
{
cnum = NULL;
}
CNumber* create(long number); // 这就是所谓的Factory Metho,即工厂方法
virtual inline ~CPalindromeNumberFactory()
{
if(cnum != NULL)
{
delete cnum;
cnum = NULL;
}
}
};
CNumber* CPalindromeNumberFactory::create(long number)
{
cnum = new CPalindromeNumber(number);
return cnum;
}
int main(void)
{
int number = 0;
int numbertype = 0;
CNumber* cnum = NULL;
CNumberFactory* cf = NULL;
while(true)
{
//system("cls");
cout << "Enter a number <0 to exit>:"; //<< endl;
cin >> number;
if(number == 0)
{
return 0;
}
cout << "Select the type of number you want to check:" << endl;
cout << "1.Prime number" << endl;
cout << "2.Complete square number" << endl;
cout << "3.Palindrome number" << endl;
cin >> numbertype;
if(numbertype < 1 || numbertype > 3)
{
cout << "Please select the right action." << endl;
}
switch(numbertype)
{
case 1:
cf = new CPrimeNumberFactory();
break;
case 2:
cf = new CCompleteSquareNumberFactory();
break;
case 3:
cf = new CPalindromeNumberFactory();
break;
default:
//system("pause");
break;
}
cnum = cf->create(number);
cnum->print();
delete cf;
cf = NULL;
//system("pause");
}
return 0;
}
各类之间的关系见如下UML类图: