increment and decrement operator overloading
下面是我一直在努力解决的问题:
Define a class named PrimeNumber that stores a prime number. The default constructor should set the prime number to 1. Add another constructor that allows the caller to set the prime number. Also, add a function to get the prime number. Finally, overload the prefix and postfix
++ and-- operators so they return aPrimeNumber object that is the next largest prime number (for++ ) and the next smallest prime number (for-- ). For example, if the object's prime number is set to 13, then invoking++ should return aPrimeNumber object whose prime number is set to 17. Create an appropriate test program for the class.
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 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | #include <iostream> #include <cstdlib> using namespace std; class PrimeNumber { public: PrimeNumber() : pNum(1) {} PrimeNumber(int setNum) : pNum(setNum) {} int getNum() const { return pNum; } PrimeNumber operator ++(); //prefix PrimeNumber operator ++(int ignoreMe); //postfix PrimeNumber operator --(); PrimeNumber operator --(int ignoreMe); bool isPrime(const int& num); private: int pNum; }; int main( ) { int x; cout <<"enter prime number =>"; cin >> x; PrimeNumber p(x); PrimeNumber hold = p++; cout <<"Value of hold =>" << hold.getNum() << endl; cout <<"Value of p =>" << p.getNum() << endl; cout <<"enter prime number =>"; cin >> x; PrimeNumber p2(x); PrimeNumber hold2 = ++p2; cout <<"Value of hold2 =>" << hold2.getNum() << endl; cout <<"Value of p2 =>" << p2.getNum() << endl; cout <<"enter prime number =>"; cin >> x; PrimeNumber p3(x); PrimeNumber hold3 = p3--; cout <<"Value of hold3 =>" << hold3.getNum() << endl; cout <<"Value of p3 =>" << p3.getNum() << endl; cout <<"enter prime number =>"; cin >> x; PrimeNumber p4(x); PrimeNumber hold4 = --p4; cout <<"Value of hold4 =>" << hold4.getNum() << endl; cout <<"Value of p4 =>" << p4.getNum() << endl; return 0; } bool PrimeNumber::isPrime(const int& num) { if (num < 2) { return false; } else if (num == 2) { return true; } else { for (int i = 2; i <= num / 2; i++) { if (num % i == 0) { return false; } } } return true; } PrimeNumber PrimeNumber::operator ++() //prefix { pNum += 1; while (!isPrime(pNum)) { pNum++; } return pNum; } PrimeNumber PrimeNumber::operator ++(int ignoreMe) //postfix { int temp = pNum += 1; while (!isPrime(pNum)) { temp = pNum; pNum++; } return temp; } PrimeNumber PrimeNumber::operator --() //prefix { pNum -= 1; while (!isPrime(pNum)) { pNum--; } return pNum; } PrimeNumber PrimeNumber::operator --(int ignoreMe) //postfix { int temp = pNum -= 1; while (!isPrime(pNum)) { temp = pNum; pNum--; } return temp; } |
此问题与递减运算符重载有关。我认为增量运算符按预期工作。如果没有,请说明。但是,对于固定后的递增和递减操作,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | Output Expected Output ---------- ------------------- enter prime number => 11 enter prime number => 11 Value of hold => 12 Value of hold => 11 Value of p => 13 Value of p => 13 enter prime number => 11 enter prime number => 11 Value of hold2 => 13 Value of hold2 => 13 Value of p2 => 13 Value of p2 => 13 enter prime number => 11 enter prime number => 11 Value of hold3 => 8 Value of hold3 => 11 Value of p3 => 7 Value of p3 => 7 enter prime number => 11 enter prime number => 11 Value of hold4 => 7 Value of hold4 => 7 Value of p4 => 7 Value of p4 => 7 |
1 2 3 4 5 6 7 8 9 10 | PrimeNumber PrimeNumber::operator --(int ignoreMe) //postfix { int temp = pNum -= 1; while (!isPrime(pNum)) { temp = pNum; temp--; } return temp; } |
此代码将永远运行,因为pnum在循环内没有更改。您的程序在最后一次输入后挂起,试图执行后缀
您的后缀操作员:
1 2 3 4 5 6 7 8 9 10 | PrimeNumber PrimeNumber::operator --(int ignoreMe) //postfix { int temp = pNum -= 1; while (!isPrime(pNum)) { temp = pNum; pNum--; } return temp; } |
仍然无效。这是正确的版本imho:
1 2 3 4 5 6 | PrimeNumber PrimeNumber::operator --(int ignoreMe) //postfix { int temp = pNum; while (!isPrime(--pNum)) {} return temp; } |
同适用于
1 2 3 4 5 6 | PrimeNumber PrimeNumber::operator ++(int ignoreMe) //postfix { int temp = pNum; while (!isPrime(++pNum)) {} return temp; } |
所以你的代码有一些基本问题。
- 通常,我们希望前缀操作符返回对自身的引用。
- 通常,返回值调用的是不必要的隐式素数构造函数。
您可以遵循以下基本规则:
前缀样式:根据需要进行递增或递减,然后返回
*this 。后缀样式:通过执行
auto copy = *this 创建自己的副本,然后调用适当的前缀操作符。
让我们尝试实现这一点:
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 | PrimeNumber & PrimeNumber::operator ++() //prefix { pNum += 1; while (!isPrime(pNum)) pNum++; return *this; } PrimeNumber PrimeNumber::operator ++(int ignoreMe) //postfix { auto copy = *this; ++(*this); return copy; } PrimeNumber & PrimeNumber::operator --() //prefix { pNum -= 1; while (!isPrime(pNum)) pNum--; return *this; } PrimeNumber PrimeNumber::operator --(int ignoreMe) //postfix { auto copy = *this; --(*this); return copy; } |
此外,当断言给出错误的结果时,测试代码应该抛出断言或类似的东西。我不需要考虑测试是对还是错。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | int main( ) { auto x = PrimeNumber(17); auto hold = x++; assert(hold.getNum() == 17); assert(x.getNum() == 19); x = PrimeNumber(18); hold = x--; assert(hold.getNum() == 18); assert(x.getNum() == 17); x = PrimeNumber(25); hold = ++x; assert(hold.getNum() == 29); assert(x.getNum() == 29); x = PrimeNumber(19); hold = --x; assert(hold.getNum() == 17); assert(x.getNum() == 17); cout <<"Success! " } |
如果所有的断言都是正确的,那么这个