这个怎么改成类模板
并设计两个拷贝构造函数哇
//(1)定义Set类,编写Set类构造函数和析构函数,使它们完成打开文件读入元素到数组中和将数组中元素写入指定的磁盘文件中;
//(2)编写集合增加一个元素的成员函数insert(int x);(注:如果集合中已有相同的元素,则不再加入)
//(3)编写删除一个元素的成员函数erase(int x);
//(4)编写判别元素是否属于集合的成员函数isInSet(int x);
//(5)编写求两个集合交的函数成员intersection(Set &s);
//(6)编写求两个集合差的成员函数intersetion(Set &s);
//(7)重载+运算符,用于求两个集合的并;
//(8)编写集合排序的成员函数sort();(从大到小排序)
//(9)重载<<运算符,用于在屏幕上输出集合元素。
#include<iostream>
#include<string.h>
#include<fstream>
#include<algorithm>
using namespace std;
class AbsCollection{
protected:
int *iPtr; //指向数组的指针
int last; //数组最后一个元素的位置
int maxSize; //数组总体长度
public:
AbsCollection(int size = 100){
maxSize = size;
iPtr = new int[maxSize];
last = -1;
};
virtual ~AbsCollection();
void OutputSet(); //输出集合中元素
};
class Set:public AbsCollection
{
private:
char *fileName; //存放数据的文件
public:
Set(int size = 100, const char *szFileName="");//从文件读取数据存入数组(要判断是否有重复元素)
virtual ~Set(); //析构函数,释放内存并将数据写入文件
void insert(int x);
void erase(int x);
int isInSet(int x); //判断x是否已经存在于集合中
friend ostream& operator<<(ostream& os, Set& s);
void intersetion(Set &s);//求集合的交(*this与s的交,结果放在*this中)
void operator+(Set &s); //求集合的并(*this与s的并,结果放在*this中)
void diff(Set &s); //求集合的差(*this与s的差,结果放在*this中)
Set& operator=(Set &s); //赋值拷贝函数
void sort(); //将集合中元素从大到小排序
};
AbsCollection::~AbsCollection()
{
if(iPtr)
delete []iPtr;
}
Set::~Set()//析构函数
{
if(fileName==NULL) return;
fstream outfile(fileName, ios::out|ios::trunc);
if(!outfile.is_open())
{
cout<<"Open Error!"<<endl;
return;
}
for(int i = 0; i<=this->last; i++)
{
outfile<<this->iPtr[i]<<" ";
}
outfile.close();
}
void Set::sort()//将集合中元素从大到小排序
{
std::sort(iPtr,iPtr+last+1,greater<int>());
}
ostream& operator<<(ostream& os, Set& s)
{
if(s.last<0)
{
os<<"Error!";
return os;
}
s.OutputSet();
return os;
}
Set& Set::operator=(Set &s)//赋值拷贝函数
{
if(iPtr)
delete []iPtr;
maxSize = s.maxSize;
this->iPtr = new int[maxSize];
last = s.last;
for(int i=0; i<=s.last; i++)
{
this->iPtr[i] = s.iPtr[i];
}
return *this;
}
void Set::diff(Set &s)//求集合的差(*this与s的差,结果放在*this中)
{
Set tempSet(maxSize);
tempSet = *this;
for(int i=0;i<=s.last;i++)
{
if(isInSet(s.iPtr[i]))
{
tempSet.erase(s.iPtr[i]);
}
}
*this = tempSet;
}
void Set::operator+(Set &s)//求集合的并(*this与s的并,结果放在*this中)
{
for(int i = 0; i<=s.last; i++)
{
if(this->isInSet(s.iPtr[i]))
{
continue;
}
else
{
this->insert(s.iPtr[i]);
}
}
}
void Set::intersetion(Set &s)//求集合的交(*this与s的交,结果放在*this中)
{
cout<<"两个集合的交集为:"<<endl;
Set tempSet(maxSize+1);
for(int i=0; i<=last; i++)
{
tempSet.iPtr[i] = this->iPtr[i];
tempSet.last++;
}
delete []iPtr;
this->last = -1;
iPtr = new int[maxSize];
for(int i = 0; i<=s.last; i++)
{
if(tempSet.isInSet(s.iPtr[i]))
{
this->insert(s.iPtr[i]);
}
}
}
void Set::erase(int x)
{
int index;
for(int j =0; j<last+1; j++)
{
if(iPtr[j]==x)
{
index = j;
break;
}
}
for(int i = index; i<last+1; i++)
{
iPtr[i] = iPtr[i+1];
}
last--;
}
int Set::isInSet(int x) //判断x是否已经存在于集合中
{
int flag = 0;
for(int i=0; i<last+1; i++)
{
if(x==iPtr[i])
{
flag = 1;
break;
}
}
return flag;
}
void Set::insert(int x)//插入元素
{
if(!isInSet(x))
{
if(last+1<maxSize)
{
last++;
iPtr[last] = x;
}
else
{
Set tempSet(maxSize+1);
for(int i=0; i<=last; i++)
{
tempSet.iPtr[i] = iPtr[i];
tempSet.last++;
}
delete []iPtr;
last = -1;
iPtr = new int[++maxSize];
for(int j = 0; j<=tempSet.last; j++)
{
iPtr[j] = tempSet.iPtr[j];
last++;
}
last++;
iPtr[last] = x;
}
}
}
void AbsCollection::OutputSet()
{
cout<<"The number of elements:"<<last+1<<endl;
for(int i=0; i<last+1; i++)
{
cout<<iPtr[i]<<" ";
}
cout<<endl;
}
Set::Set(int size, const char *szFileName):AbsCollection(size)//从文件读取数据存入数组
{
if(szFileName == "")
{
fileName = NULL;
return;
}
fileName = new char[strlen(szFileName)+1];
strcpy(fileName,szFileName);
ifstream infile(szFileName);
if(!infile.is_open())
{
cout<<"Open error!";
return;
}
int temp;
while(infile>>temp)
{
if(!isInSet(temp))
{
insert(temp);
}
}
infile.close();
}
int main()
{
Set set1(0,"file1.txt");
set1.OutputSet();//测试 OutputSet()
getchar();
Set set2(0,"file2.txt");
set2.OutputSet();
getchar();
set1.insert(30);//测试insert()
cout<<set1;//测试重载<<
Set set3(100);
getchar();
set1.diff(set2);//补集
set1.sort();
cout<<set1;
// set1.operator+(set2);//+并集
// set1.intersetion(set2);//交集
// cout<<set1;
// set1.sort();
// set3 = set1;//测试重载=
// cout<<set3;
// getchar();
return 0;
}
类模板,可以理解为实现功能相同,只是数据类型或返回类型、形参类型不同,相当于设计一个通用类。
模板如下:
模板template<typename T>
,相当于你将参数都统一为T
类型,传入的参数也是T
,等到具体调用Compare<int> com1(3,7);
再声明数据类型。
#include<iostream.h>
template<typename T> //模板声明,其中T为类型参数
class Compare{
public:
Compare(T i,T j)
{
x = i;
y = j;
}
T max()
{
return (x>y)?x:y;
}
private:
T x,y;
};
int main()
{
Compare<int>com1(3,7); //用类模板定义对象com1,此时T被int替代
Compare<double>com2(12.34,56.78);//用类模板定义对象com2,此时T被double替代
Compare<char>com3('a','x'); //用类模板定义对象com3,此时T被char替代
return 0;
}
至于题主所说的设计两个拷贝构造函数我不太清楚要求。
若有帮助,可以采纳。
两个拷贝构造函数
#include <iostream>
using namespace std;
class Line
{
public:
int getLength( void );
Line( int len ); // 简单的构造函数
Line( const Line &obj); // 拷贝构造函数
~Line(); // 析构函数
private:
int *ptr;
};
// 成员函数定义,包括构造函数
Line::Line(int len)
{
cout << "调用构造函数" << endl;
// 为指针分配内存
ptr = new int;
*ptr = len;
}
Line::Line(const Line &obj)
{
cout << "调用拷贝构造函数并为指针 ptr 分配内存" << endl;
ptr = new int;
*ptr = *obj.ptr; // 拷贝值
}
Line::~Line(void)
{
cout << "释放内存" << endl;
delete ptr;
}
int Line::getLength( void )
{
return *ptr;
}
void display(Line obj)
{
cout << "line 大小 : " << obj.getLength() <<endl;
}
// 程序的主函数
int main( )
{
Line line1(10);
Line line2 = line1; // 这里也调用了拷贝构造函数
display(line1);
display(line2);
return 0;
}
类和拷贝构造函数
#include<iostream>
class A {
public:
A(int a = 0) :_a(a){};
A(const A& a) {
_a = a._a;
std::cout << "拷贝构造函数" << std::endl;
}
int _a;
};
A Test() {
A a(2);
return a;
}
int main() {
auto tmp = Test();
std::cout << tmp._a << std::endl;
return 0;
}
————————————————
参考
https://blog.csdn.net/weixin_42562387/article/details/113556797
http://c.biancheng.net/view/151.html