#include <iostream> using namespace std; //在类外进行前置声明 // 友元函数在类外面实现,并且都在同一个CPP文件中, //需要在前面对类和对应操作符重载函数进行前置声明。 // 同时在类内部声明的对应函数需要在参数链表前加入 "<T>"。 template <class T1, class T2> class Person; template <class T1, class T2> std::ostream& operator<<(std::ostream& os, Person<T1, T2>& p); //类模板 类外实现 //类模板 template <class T1, class T2> class Person { public: //模板类中使用友元 //重载左移操作符,用于直接打印输出 //方法1 //template <class T1, class T2> //定要加 这句,不过这样的写法在linux不能通过 //friend std::ostream& operator<<(std::ostream& os, Person<T1, T2>& p); //方法2在操作符后加 <T1,T2>,同时进行类前置声明 //方法1 在VS中可以便宜,但 要在Linux下会出错 friend std::ostream& operator<<<T1,T2>(std::ostream& os, Person<T1, T2>& p); Person(T1 id, T2 age); void showPerson(); private: T1 mId_; T2 mAge_; }; //声明和实现分开时,我们需要对函数的声明做特殊处理, //注意,这里类名应是Person<T1,T2> template <class T1, class T2> Person<T1, T2>::Person(T1 id, T2 age) { this->mAge_ = age; this->mId_ = id; } template <class T1, class T2> void Person<T1, T2>::showPerson() { std::cout << "id.....:" << mId_ << ",age:" << mAge_ << std::endl; } //通过重载左移操作符,用于直接打印输出 template <class T1, class T2> std::ostream& operator<<(std::ostream& os, Person<T1, T2>& p) { std::cout << "operator--- id: " << p.mId_ << ",age:" << p.mAge_ << std::endl; return os; } //类模板在类外实现时,不要滥用友元 void testShow() { //函数模板在调用时,可以自动进行类型推导 //类模板必须显式声明 Person<int, int> person(12, 11111); //person.showPerson(); std::cout << "ddd: " << person << std::endl; } int main() { testShow(); return 0; }
时间: 2024-04-01 14:32:01 浏览: 61
这段代码是关于类模板在类外实现的例子,其中定义了一个类模板 Person,包含两个类型模板参数 T1 和 T2,以及一个构造函数和一个成员函数 showPerson。此外还定义了一个友元函数 operator<< 重载左移操作符,用于直接打印输出。在类外实现时,需要进行前置声明,并在声明和实现中加上模板参数类型。这里还提醒不要滥用友元,因为友元的使用破坏了类的封装性,应该尽量避免使用。
相关问题
1.定义一个复数类Complex,重载前置自增“++”运算符及后置自增“++”运算符,使之能用于复数的自增运算。 注:复数的自增是让复数的实部和虚部同时增加1.主函数示例如下: #include <iostream> using namespace std; /*********在begin和end之间填入代码,实现complex类的定义,重载前置++运算符和重载后置++运算符及display()函数********/ /***********begin*************/ void Complex::display() { if(real==0) { if(imag>0) cout<<imag<<"i"; else if(imag==0) cout<<real; else cout<<imag<<"i"; } else { if(imag>0) cout<<real<<"+"<<imag<<"i"; else if(imag==0) cout<<real; else cout<<real<<imag<<"i"; } } /***********end************/ int main() { Complex c1,c2; cin>>c1.real>>c1.imag; c1.display(); cout<<endl; ++c1; c2=c1++; c2.display(); cout<<endl; c1.display(); } 2.已知矩阵为2行3列,重载流插入运算符“<<”和流提取运算符">>",使之能完成矩阵的输入和输出。 主函数示例如下: #include <iostream> using namespace std; //请在begin和end间完成Matrix类的编写,重载>>及<<运算符,建议重载为友元函数 /*********begin**********/ /*********end*********/ int main() { Matrix m1; cin>>m1; cout<<"output matrix"<<endl; cout<<m1; }
下面是两个问题的代码实现:
1. 定义一个复数类Complex,重载前置自增“++”运算符及后置自增“++”运算符,使之能用于复数的自增运算。
```c++
#include <iostream>
using namespace std;
class Complex {
private:
double real, imag;
public:
Complex(double r = 0, double i = 0) : real(r), imag(i) {}
// 前置自增
Complex& operator++() {
real++;
imag++;
return *this;
}
// 后置自增
Complex operator++(int) {
Complex temp(*this);
real++;
imag++;
return temp;
}
void display() {
if (real == 0) {
if (imag > 0)
cout << imag << "i";
else if (imag == 0)
cout << real;
else
cout << imag << "i";
}
else {
if (imag > 0)
cout << real << "+" << imag << "i";
else if (imag == 0)
cout << real;
else
cout << real << imag << "i";
}
}
};
int main() {
Complex c1, c2;
cin >> c1.real >> c1.imag;
c1.display();
cout << endl;
++c1;
c2 = c1++;
c2.display();
cout << endl;
c1.display();
return 0;
}
```
在上面的代码中,我们重载了前置自增和后置自增运算符,并定义了一个display()函数,用于输出复数对象的值。在主函数中,我们创建了两个复数对象,对它们进行了自增运算,并输出了结果。
2. 已知矩阵为2行3列,重载流插入运算符“<<”和流提取运算符“>>”,使之能完成矩阵的输入和输出。
```c++
#include <iostream>
using namespace std;
class Matrix {
private:
int data[2][3];
public:
friend istream& operator>>(istream& is, Matrix& m) {
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
is >> m.data[i][j];
}
}
return is;
}
friend ostream& operator<<(ostream& os, const Matrix& m) {
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
os << m.data[i][j] << " ";
}
os << endl;
}
return os;
}
};
int main() {
Matrix m1;
cin >> m1;
cout << "output matrix" << endl;
cout << m1;
return 0;
}
```
在上面的代码中,我们定义了一个Matrix类,其中包含了一个2行3列的矩阵。我们重载了流插入运算符“>>”和流提取运算符“<<”,并实现了矩阵的输入和输出。在主函数中,我们创建了一个Matrix对象,对它进行了输入,并输出了结果。
2.定义了Money类请补充完代码 #include <iostream> using namespace std; class Money { int Yuan, Jiao; // 元、角 public: Money(int y = 0, int j = 0) Money(double d) Money operator++(); //①用成员函数实现前置++ Money operator++(int); //②用成员函数实现后置++ friend Money operator--(Money &m); //③用友元函数实现前置-- friend Money operator--(Money &m, int); //④用友元函数实现后置-- operator double(); friend ostream & operator<<(ostream & out,Money & m); int main(void) { Money m(15, 3), m1, m2, m3, m4; cout<<"m:"<<m;//m.Show("m"); m1 = ++m; cout << "m1=++m;\n"<<"m1:"<<m1<<"m:"<<m; m2 = m++; cout << "m2=m++;\n"<<"m2:"<<m2<<"m:"<<m; m3 = --m; cout << "m3=--m;\n"<<"m3:"<<m3<<"m:"<<m; m4 = m--; cout << "m4=m--;\n"<<"m4:"<<m4<<"m:"<<m; Money m5 = m4 + 8.5; //A行 cout<<"m5= m4 + 8.5\nm5:"<<m5; return 0; }
下面是补充完整的Money类代码:
```c++
#include <iostream>
using namespace std;
class Money {
int Yuan, Jiao; // 元、角
public:
Money(int y = 0, int j = 0) : Yuan(y), Jiao(j) {}
Money(double d) {
Yuan = static_cast<int>(d);
Jiao = static_cast<int>((d - Yuan) * 10 + 0.5);
}
Money operator++(); //①用成员函数实现前置++
Money operator++(int); //②用成员函数实现后置++
friend Money operator--(Money &m); //③用友元函数实现前置--
friend Money operator--(Money &m, int);//④用友元函数实现后置--
operator double() { return Yuan + Jiao / 10.0; }
friend ostream & operator<<(ostream & out,Money & m);
Money operator+(double x) {
Money temp(*this);
temp.Yuan += static_cast<int>(x);
temp.Jiao += static_cast<int>((x - static_cast<int>(x)) * 10 + 0.5);
return temp;
}
};
Money Money::operator++() {
Jiao++;
if(Jiao == 10) {
Jiao = 0;
Yuan++;
}
return *this;
}
Money Money::operator++(int) {
Money temp(*this);
Jiao++;
if(Jiao == 10) {
Jiao = 0;
Yuan++;
}
return temp;
}
Money operator--(Money &m) {
m.Jiao--;
if(m.Jiao == -1) {
m.Jiao = 9;
m.Yuan--;
}
return m;
}
Money operator--(Money &m, int) {
Money temp(m);
m.Jiao--;
if(m.Jiao == -1) {
m.Jiao = 9;
m.Yuan--;
}
return temp;
}
ostream & operator<<(ostream & out, Money & m) {
out << m.Yuan << "." << m.Jiao << "元";
return out;
}
int main(void) {
Money m(15, 3), m1, m2, m3, m4;
cout << "m:" << m << endl;
m1 = ++m;
cout << "m1=++m;\n" << "m1:" << m1 << "m:" << m << endl;
m2 = m++;
cout << "m2=m++;\n" << "m2:" << m2 << "m:" << m << endl;
m3 = --m;
cout << "m3=--m;\n" << "m3:" << m3 << "m:" << m << endl;
m4 = m--;
cout << "m4=m--;\n" << "m4:" << m4 << "m:" << m << endl;
Money m5 = m4 + 8.5; //A行
cout << "m5= m4 + 8.5\nm5:" << m5 << endl;
return 0;
}
```
Money类中的主要成员函数和友元函数功能如下:
- Money(int y = 0, int j = 0):构造函数,初始化元和角;
- Money(double d):构造函数,根据浮点数d初始化元和角;
- Money operator++():前置++,使元和角都加1;
- Money operator++(int):后置++,使元和角都加1,但返回原对象的副本;
- friend Money operator--(Money &m):前置--,使元和角都减1;
- friend Money operator--(Money &m, int):后置--,使元和角都减1,但返回原对象的副本;
- operator double():类型转换运算符,将对象转换为浮点数;
- friend ostream & operator<<(ostream & out,Money & m):输出运算符,输出对象的元和角;
- Money operator+(double x):重载+运算符,将Money对象和浮点数相加,返回结果Money对象。
在main函数中,先创建一个Money对象m(15, 3),然后依次调用前置++、后置++、前置--、后置--和重载+运算符,最后将结果输出。
阅读全文