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 constructor
HugeInt( const char * ); // conversion constructor
// addition operator; HugeInt + HugeInt
HugeInt operator+( const HugeInt & ) const;
// addition operator; HugeInt + int
HugeInt operator+( int ) const;
// addition operator;
// HugeInt + string that represents large integer value
HugeInt 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 0
for (int i = 0; i < digits; i++) {
integer[i] = 0;
}
// Store digits in reverse order
for (int i = digits - 1; value != 0 && i >= 0; i--) {
integer[i] = value % 10;
value /= 10;
}
}
HugeInt::HugeInt(const char *str) {
// Initialize all digits to 0
for (int i = 0; i < digits; i++) {
integer[i] = 0;
}
int len = strlen(str);
int j = digits - 1;
// Store digits in reverse order
for (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 zeros
return (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 zeros
if (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;
};
//StudybarCommentEnd
Point::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; //输出GetX
delete ptr1; //删除对象,自动调用析构函数
cout << "Step two: " << endl;
ptr1 = new Point(1,2);
cout << ptr1->getX() << endl; //输出GetX
delete 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->mallocSize
unsigned int capacity() const {
return mallocSize;
}
// for the array[i]=someT.
T& operator[](unsigned int i) {
return array[i];
}
};