1、 HugeInt類:構造、+、cout
Description:
32位整數的計算機可以表示整數的范圍近似為-20億到+20億。在這個范圍內操作一般不會出現問題,但是有的應用程序可能需要使用超出上述范圍的整數。C++可以滿足這個需求,創建功能強大的新的數據類型。
定義一個HugeInt類,使用一個數組存儲大整數的每一位。如 short integer[ 40 ]; 即可實現存儲位數為40位的整數。暫不考慮負數。請根據主函數為該類:
1)定義兩個構造,分別接受int和string類型的參數;當參數為string類型時,可以使用字符串處理函數將string類型轉換為數值類型。
2)重載+運算,分別能夠實現兩個HugeInt對象相加,HugeInt與int相加,HugeInt與string相加。提示,先實現兩個HugeInt相加,當HugeInt與int相加時,可以將int通過轉換構造函數轉換為HugeInt類型,然后調用兩個HugeInt相加。HugeInt與string相加亦如此。
3)重載<<運算符。
注意:程序前綴、后綴代碼已給出。
Sample Input:
無
Sample Output:
//StudybarCommentBegin
#include <iostream>
#include <cctype> // isdigit function prototype
#include <cstring> // strlen function prototype
using namespace std;class HugeInt
{friend ostream &operator<<( ostream &, const HugeInt & );
public:static const int digits = 30;HugeInt( long = 0 ); // conversion/default constructorHugeInt( const char * ); // conversion constructor// addition operator; HugeInt + HugeIntHugeInt operator+( const HugeInt & ) const;// addition operator; HugeInt + intHugeInt operator+( int ) const;// addition operator;// HugeInt + string that represents large integer valueHugeInt operator+( const char * ) const;int getLength() const;
private:short integer[ digits ];
}; // end class HugeInt//StudybarCommentEnd// Implementation of HugeInt class
HugeInt::HugeInt(long value) {// Initialize all digits to 0for (int i = 0; i < digits; i++) {integer[i] = 0;}// Store digits in reverse orderfor (int i = digits - 1; value != 0 && i >= 0; i--) {integer[i] = value % 10;value /= 10;}
}HugeInt::HugeInt(const char *str) {// Initialize all digits to 0for (int i = 0; i < digits; i++) {integer[i] = 0;}int len = strlen(str);int j = digits - 1;// Store digits in reverse orderfor (int i = len - 1; i >= 0 && j >= 0; i--) {if (isdigit(str[i])) {integer[j--] = str[i] - '0';}}
}HugeInt HugeInt::operator+(const HugeInt &op2) const {HugeInt temp;int carry = 0;for (int i = digits - 1; i >= 0; i--) {temp.integer[i] = integer[i] + op2.integer[i] + carry;if (temp.integer[i] > 9) {temp.integer[i] %= 10;carry = 1;} else {carry = 0;}}return temp;
}HugeInt HugeInt::operator+(int op2) const {return *this + HugeInt(op2);
}HugeInt HugeInt::operator+(const char *op2) const {return *this + HugeInt(op2);
}int HugeInt::getLength() const {int i;for (i = 0; (i < digits) && (integer[i] == 0); i++); // skip leading zerosreturn (i == digits) ? 1 : (digits - i);
}ostream &operator<<(ostream &output, const HugeInt &num) {int i;for (i = 0; (i < HugeInt::digits) && (num.integer[i] == 0); i++); // skip leading zerosif (i == HugeInt::digits) {output << 0;} else {for (; i < HugeInt::digits; i++) {output << num.integer[i];}}return output;
}//StudybarCommentBegin
int main()
{HugeInt n1( 7654321 );HugeInt n2( 7891234 );HugeInt n3( "99999999999999999999999999999" );HugeInt n4( "1" );HugeInt result;cout << "n1 is " << n1 << "\nn2 is " << n2<< "\nn3 is " << n3 << "\nn4 is " << n4<< "\nresult is " << result << "\n\n";result = n1 + n2;cout << n1 << " + " << n2 << " = " << result << "\n\n";cout << n3 << " + " << n4 << "\n= " << ( n3 + n4 ) << "\n\n";result = n1 + 9;cout << n1 << " + " << 9 << " = " << result << endl;result = n2 + "10000";cout << n2 << " + " << "10000" << " = " << result << endl;return 0;
} // end main//StudybarCommentEnd
2、對象指針定義形式——代碼糾正
對象指針定義形式
類名 *對象指針名;
例:
Point a(5,10);
Piont *ptr;
ptr=&a;
通過指針訪問對象成員
對象指針名->成員名
例:ptr->getx() 相當于 (*ptr).getx();
例6-12使用指針來訪問Point類的成員
//6_12.cpp
#include
using namespace std;
class Point {
public:
Point(int x = 0, int y = 0) : x(x), y(y) { }
int getX() const { return this->x; }
int getY() const { return y; }
private:
int x, y;
};
int main() {
Point a(4, 5);
Point p1 = &a; //定義對象指針,用a的地址初始化
cout << p1.getX() << endl;//用指針訪問對象成員
cout << a->getY() << endl; //用對象名訪問對象成員
return 0;
}
本題輸出結果
4
5
#include <iostream>
using namespace std;class Point {
public:Point(int x = 0, int y = 0) : x(x), y(y) { }int getX() const { return this->x; }int getY() const { return y; }
private:int x, y;
};int main() {Point a(4, 5);Point *p1 = &a; // 定義對象指針,用a的地址初始化cout << p1->getX() << endl; // 用指針訪問對象成員cout << a.getY() << endl; // 用對象名訪問對象成員return 0;
}
3、動態創建對象舉例
動態內存分配
動態申請內存操作符 new
new 類型名T(初始化參數列表)
功能:在程序執行期間,申請用于存放T類型對象的內存空間,并依初值列表賦以初值。
結果值:成功:T類型的指針,指向新分配的內存;失敗:拋出異常。
釋放內存操作符delete
delete 指針p
功能:釋放指針p所指向的內存。p必須是new操作的返回值。
本題給出了前綴,本題程序,應該和下列代碼等價!
例6-16 動態創建對象舉例
#include
using namespace std;
class Point {
public:
Point() : x(0), y(0) {
cout<<“Default Constructor called.”<<endl;
}
Point(int x, int y) : x(x), y(y) {
cout<< “Constructor called.”<<endl;
}
~Point() { cout<<“Destructor called.”<<endl; }
int getX() const { return x; }
int getY() const { return y; }
void move(int newX, int newY) {
x = newX;
y = newY;
}
private:
int x, y;
};
int main() {
cout << "Step one: " << endl;
Point *ptr1 = new Point; //調用默認構造函數
cout<getX()<<endl; //輸出GetX
delete ptr1; //刪除對象,自動調用析構函數
cout << "Step two: " << endl;
ptr1 = new Point(1,2);
cout<getX()<<endl; //輸出GetX
delete ptr1;
return 0;
}
//StudybarCommentBegin
#include <iostream>
using namespace std;
class Point {
public:Point();Point(int x, int y);~Point();int getX() const; int getY() const; void move(int newX, int newY);
private:int x, y;
};
//StudybarCommentEndPoint::Point() : x(0), y(0) {cout << "Default Constructor called." << endl;
}Point::Point(int x, int y) : x(x), y(y) {cout << "Constructor called." << endl;
}Point::~Point() {cout << "Destructor called." << endl;
}int Point::getX() const {return x;
}int Point::getY() const {return y;
}void Point::move(int newX, int newY) {x = newX;y = newY;
}int main() {cout << "Step one: " << endl;Point *ptr1 = new Point; //調用默認構造函數cout << ptr1->getX() << endl; //輸出GetXdelete ptr1; //刪除對象,自動調用析構函數cout << "Step two: " << endl;ptr1 = new Point(1,2);cout << ptr1->getX() << endl; //輸出GetXdelete ptr1;return 0;
}
4、 動態創建對象數組舉例
例6-17 動態創建對象數組舉例
分配和釋放動態數組
分配:new 類型名T [ 數組長度 ]
數組長度可以是任何表達式,在運行時計算
釋放:delete[] 數組名p
釋放指針p所指向的數組。
p必須是用new分配得到的數組首地址。
例6-17 動態創建對象數組舉例
#include<iostream>using namespace std;#include <iostream>using namespace std;class Point {public:Point() : x(0), y(0) {cout<<"Default Constructor called."<<endl;}Point(int x, int y) : x(x), y(y) {cout<< "Constructor called."<<endl;}~Point() { cout<<"Destructor called."<<endl; }int getX() const { return x; }int getY() const { return y; }void move(int newX, int newY) {x = newX;y = newY;}private:int x, y;};int main() {
Point *ptr = new Point[2]; //創建對象數組
ptr[0].move(5, 10); //通過指針訪問數組元素的成員
cout<<ptr[0].getY()<<endl;
ptr[1].move(15, 20); //通過指針訪問數組元素的成員
cout<<ptr[1].getY()<<endl;
cout << "Deleting..." << endl;
delete[] ptr; //刪除整個對象數組
return 0;
}
5、淺層復制與深層復制
淺層復制
實現對象間數據元素的一一對應復制。
深層復制
當被復制的對象數據成員是指針類型時,不是復制該指針成員本身,而是將指針所指對象進行復制
例6-21 對象的淺層復制
#include
#include
using namespace std;
class Point {
//類的聲明同例6-16
//……
};
class ArrayOfPoints {
//類的聲明同例6-18
//……
};
int main() {
int count;
cout << "Please enter the count of points: ";
cin >> count;
ArrayOfPoints pointsArray1(count); //創建對象數組
pointsArray1.element(0).move(5,10);
pointsArray1.element(1).move(15,20);
ArrayOfPoints pointsArray2(pointsArray1); //創建副本
cout << “Copy of pointsArray1:” << endl;
cout << "Point_0 of array2: " << pointsArray2.element(0).getX() << ", "
<< pointsArray2.element(0).getY() << endl;
cout << "Point_1 of array2: " << pointsArray2.element(1).getX() << ", "
<< pointsArray2.element(1).getY() << endl;
pointsArray1.element(0).move(25, 30);
pointsArray1.element(1).move(35, 40);
cout<<“After the moving of pointsArray1:”<<endl;
cout << "Point_0 of array2: " << pointsArray2.element(0).getX() << ", "
<< pointsArray2.element(0).getY() << endl;
cout << "Point_1 of array2: " << pointsArray2.element(1).getX() << ", "
<< pointsArray2.element(1).getY() << endl;
return 0;
}
運行結果如下:
Please enter the number of points:2
Default Constructor called.
Default Constructor called.
Copy of pointsArray1:
Point_0 of array2: 5, 10
Point_1 of array2: 15, 20
After the moving of pointsArray1:
Point_0 of array2: 25, 30
Point_1 of array2: 35, 40
Deleting…
Destructor called.
Destructor called.
Deleting…
接下來程序出現運行錯誤。
例6-22 對象的深層復制
#include
#include
using namespace std;
class Point { //類的聲明同例6-16
};
class ArrayOfPoints {
public:
ArrayOfPoints(const ArrayOfPoints& pointsArray);
//其他成員同例6-18
};
ArrayOfPoints::ArrayOfPoints(const ArrayOfPoints& v) {
size = v.size;
points = new Point[size];
for (int i = 0; i < size; i++)
points[i] = v.points[i];
}
int main() {
//同例6-20
}
程序的運行結果如下:
Please enter the number of points:2
Default Constructor called.
Default Constructor called.
Default Constructor called.
Default Constructor called.
Copy of pointsArray1:
Point_0 of array2: 5, 10
Point_1 of array2: 15, 20
After the moving of pointsArray1:
Point_0 of array2: 5, 10
Point_1 of array2: 15, 20
Deleting…
Destructor called.
Destructor called.
Deleting…
Destructor called.
Destructor called.
#include <iostream>
#include <cassert>
using namespace std;class Point {
public:Point() : x(0), y(0) {cout << "Default Constructor called." << endl;}~Point() {cout << "Destructor called." << endl;}void move(int newX, int newY) { x = newX; y = newY; }int getX() const { return x; }int getY() const { return y; }
private:int x, y;
};class ArrayOfPoints {
public:ArrayOfPoints(int size) : size(size) {points = new Point[size];}// 復制構造函數(深層復制)ArrayOfPoints(const ArrayOfPoints& v) {size = v.size;points = new Point[size];for (int i = 0; i < size; i++)points[i] = v.points[i];}~ArrayOfPoints() {cout << "Deleting..." << endl;delete[] points;}Point& element(int index) {assert(index >= 0 && index < size);return points[index];}private:Point* points;int size;
};int main() {int count;cout << "Please enter the number of points:" << endl;cin >> count;ArrayOfPoints pointsArray1(count); //創建對象數組pointsArray1.element(0).move(5, 10);pointsArray1.element(1).move(15, 20);ArrayOfPoints pointsArray2(pointsArray1); //創建副本(深層復制)cout << "Copy of pointsArray1:" << endl;cout << "Point_0 of array2: " << pointsArray2.element(0).getX() << ", " << pointsArray2.element(0).getY() << endl;cout << "Point_1 of array2: " << pointsArray2.element(1).getX() << ", " << pointsArray2.element(1).getY() << endl;pointsArray1.element(0).move(25, 30);pointsArray1.element(1).move(35, 40);cout << "After the moving of pointsArray1:" << endl;cout << "Point_0 of array2: " << pointsArray2.element(0).getX() << ", " << pointsArray2.element(0).getY() << endl;cout << "Point_1 of array2: " << pointsArray2.element(1).getX() << ", " << pointsArray2.element(1).getY() << endl;return 0;
}
6、動態數組——基本模板類
本題目有后綴
題目描述:
動態數組,是相對于靜態數組而言。靜態數組的長度是編程時程序員預先定義好的,在整個程序運行中,數組大小無法改變。
而動態數組則不然,它可以隨程序運行的需要而在運行時重新指定大小。
動態數組的內存空間是從堆(heap)上分配(即動態分配)的。是通過執行new(或malloc等函數)操作,而為其分配存儲空間。當程序執行到這些語句時,才為其分配。
對于動態數組類所申請的內存,在使用完必須由程序員自己釋放,否則嚴重會引起內存泄露。
所以內存的申請一定要有借有還,才能再借不難,也要注意,不能多還。
已知動態數組模板類的定義如下。
請補充完整
1、構造函數
2、析構函數
3、返回空間大小的 capacity() 函數
4、operator[] 重載
template
class DynamicArray {
private:
T* array; //pointer ,一個T類型的指針
unsigned int mallocSize; //分配空間的大小。
public:
//Constructors
// cout<<endl<< “new T[”<mallocSize<<“] malloc “<< this->mallocSize << “*”<<sizeof(T)<<”=”<mallocSize *sizeof(T)<<" bytes memory in heap";
DynamicArray(unsigned length, const T &content) ; // mallocSize=length; 設置每個元素的初始內容是 content;
// Destructors
// cout<<endl<< “delete[] array free “<< this->mallocSize << “*”<<sizeof(T)<<”=”<mallocSize *sizeof(T)<<" bytes memory in heap";
~DynamicArray();
//return the this->mallocSize
unsigned int capacity() const;
// for the array[i]=someT.
T& operator[](unsigned int i) ;
};
輸入一個整數
輸出請分析參見下面的用例和程序后綴。
樣例輸入:
3
樣例輸出
new T[3] malloc 34=12 bytes memory in heap
new T[3] malloc 38=24 bytes memory in heap
capacity:3
-1 -1 -1
-2.1 -2.1 -2.1
0 1 2
0 1.1 2.2
delete[] array free 38=24 bytes memory in heap
delete[] array free 34=12 bytes memory in heap
#include <iostream>
using namespace std;template <typename T>
class DynamicArray {
private:T* array; //pointer ,一個T類型的指針unsigned int mallocSize; //分配空間的大小。public://Constructors // cout<<endl<< "new T["<<this->mallocSize<<"] malloc "<< this->mallocSize << "*"<<sizeof(T)<<"="<<this->mallocSize *sizeof(T)<<" bytes memory in heap";DynamicArray(unsigned length, const T &content) {mallocSize = length;array = new T[length];for (unsigned int i = 0; i < length; ++i) {array[i] = content;}cout << "new T[" << mallocSize << "] malloc " << mallocSize << "*" << sizeof(T) << "=" << mallocSize * sizeof(T) << " bytes memory in heap\n";}// Destructors// cout<<endl<< "delete[] array free "<< this->mallocSize << "*"<<sizeof(T)<<"="<<this->mallocSize *sizeof(T)<<" bytes memory in heap";~DynamicArray() {cout << endl << "delete[] array free " << mallocSize << "*" << sizeof(T) << "=" << mallocSize * sizeof(T) << " bytes memory in heap";delete[] array;}//return the this->mallocSizeunsigned int capacity() const {return mallocSize;}// for the array[i]=someT.T& operator[](unsigned int i) {return array[i];}
};