04737_C++程序设计_第5章_特殊函数和成员

时间:2023-03-08 22:14:50

例5.1

分析下面程序中析构函数与构造函数的调用顺序。

 #include<iostream>

 using namespace std;

 class object
{
private:
int val;
public:
object() :val()
{
cout << "Ddfault constructor for object" << endl;
}
object(int i) :val(i)
{
cout << "Constructor for object " << val << endl;
}
~object()
{
cout << "Destructor for object" << val << endl;
}
}; class container
{
private:
object one;//初始化顺序与对象成员产生的顺序有关
object two;//排在前面的先初始化
int data;
public:
container() :data()
{
cout << "Ddfault constructor for object" << endl;
}
container(int i, int j, int k);
~container()
{
cout << "Destructor for object" << data << endl;
}
}; container::container(int i, int j, int k) :two(i), one(j)//与初始化列表顺序无关
{
data = k;
cout << "Constructor for container " << data << endl;
} void main()
{
container obj, anObj(, , ); system("pause");
}

例5.2

分析下面程序的输出结果。

 class Test
{
static int x;//静态数据成员
int n;
public:
Test()
{ }
Test(int a, int b)
{
x = a;
n = b;
}
static int func()
{
return x;//静态成员函数
};
static void sfunc(Test&r, int a)
{
r.n = a;//静态成员函数
}
int Getn()
{
return n;//非静态成员函数
}
}; int Test::x = ;//初始化静态数据成员 #include<iostream> using namespace std; void main()
{
cout << Test::func();//x在产生对象之前即存在,输出25 Test b, c;
b.sfunc(b, );//设置对象b的数据成员n cout << " " << b.Getn();
cout << " " << b.func();//x属于所有对象,输出25
cout << " " << c.func();//x属于所有对象,输出25 Test a(, );//将类的x值改为24 cout << " " << a.func() << " " << b.func() << " " << b.func() << endl; system("pause");
}

5.3

使用静态对象的例子

 #include<iostream>

 using namespace std;

 class test
{
private:
int n;
public:
test(int i)
{
n = i;
cout << "constructor:" << i << endl;
}
~test()
{
cout << "destructor:" << n << endl;
}
int getn()
{
return n;
}
void inc()
{
++n;
}
}; void main()
{
cout << "loop start:" << endl; for (int i = ; i < ; i++)
{
static test a();
test b();
a.inc();
b.inc();
cout << "a.n=" << a.getn() << endl;
cout << "b.n=" << b.getn() << endl;
} cout << "loop end." << endl;
cout << "Exit main()" << endl; system("pause");
}

例5.4

使用友元函数计算两点距离的例子。

 #include <iostream>
#include <cmath>//也可以使用头文件<math.h>
using namespace std;
class Point
{
private:
double X, Y;
public:
Point(double xi, double yi)
{
X = xi, Y = yi;
}
double GetX()
{
return X;
}
double GetY()
{
return Y;
}
friend double distances(Point&, Point&);//声明友元函数
};
double distances(Point& a, Point& b)//像普通函数一样定义友元函数
{
double dx = a.X - b.X;//可以访问对象a的成员
double dy = a.Y - b.Y;//可以访问对象b的成员
return sqrt(dx*dx + dy*dy);
}
void main()
{
Point p1(3.5, 5.5), p2(4.5, 6.5);
cout << "The distance is " << distances(p1, p2) << endl; system("pause");
}

例5.5

类One的对象通过友元函数访问类Two的对象的私有数据。

 #include <iostream>
using namespace std;
class Two;//先声明类Two以便类One引用Two&
class One
{
private:
int x;
public:
One(int a)
{
x = a;
}
int Getx()
{
return x;
}
void func(Two&);//声明本类的成员函数,参数为Two类的引用
};
class Two
{
private:
int y;
public:
Two(int b)
{
y = b;
}
int Gety()
{
return y;
}
friend void One::func(Two&);//声明类One的函数为友元函数
};
void One::func(Two& r)//定义类One的函数成员
{
r.y = x;//修改类Two的数据成员
}
void main()
{
One Obj1();
Two Obj2();
cout << Obj1.Getx() << " " << Obj2.Gety() << endl;
Obj1.func(Obj2);
cout << Obj1.Getx() << " " << Obj2.Gety() << endl; system("pause");
}

例5.6

类One的对象可以通过任意一个成员函数访问类Two的对象的私有数据。

 #include <iostream>

 using namespace std;

 class Two
{
int y;
public:
friend class One;
}; class One
{
int x;
public:
One(int a, Two&r, int b)
{
x = a;
r.y = b;
}
void Display(Two&);
}; void One::Display(Two&r)
{
cout << x << " " << r.y << endl;
} void main()
{
Two Obj2;
One Obj1(, Obj2, );
Obj1.Display(Obj2); system("pause");
}

例5.7

常数据成员初始化和常引用作为函数参数。

 #include <iostream>

 using namespace std;

 class Base
{
private:
int x;
const int a;//常数据成员只能通过初始化列表来获得初值
static const int b;//静态常数据成员
const int& r;//常引用只能通过初始化列表来获得初值
public:
Base(int, int);
void Show()
{
cout << x << "," << a << "," << b << "," << r << endl;
}
void Display(const double& r)
{
cout << r << endl;
}
}; const int Base::b = ;//静态常数据成员在类外初始化 Base::Base(int i, int j) :x(i), a(j), r(x)//初始化列表
{ } void main()
{
Base a1(, ), a2(, );
a1.Show();
a2.Show();
a2.Display(3.14159);//常引用作为函数参数 system("pause");
}

例5.8

const对象调用const成员函数。

 #include <iostream>

 using namespace std;

 class Base
{
private:
double x, y;
const double p;
public:
Base(double m, double n, double d) :p(d)//通过初始化列表来获得初值
{
x = m;
y = n;
}
void Show();
void Show() const;
}; void Base::Show()
{
cout << x << "," << y << " p=" << p << endl;
} void Base::Show() const//定义时必须也使用const
{
cout << x << "," << y << " const p=" << p << endl;
} void main()
{
Base a(8.9, 2.5, 3.1416);
const Base b(2.5, 8.9, 3.14);
b.Show();//调用void Show() const
a.Show();//调用void Show() system("pause");
}

例5.9

const函数返回的常量对象与其他常量对象一起使用。

 #include <iostream>

 using namespace std;

 class ConstFun
{
public:
int f5() const
{
return ;//返回常量对象
}
int Obj()
{
return ;
}
}; void main()
{
ConstFun s;//一般对象
const int i = s.f5();//对象s使用f5()初始化常整数
const int j = s.Obj();//对象s使用Obj()初始化常整数
int x = s.Obj();//对象s使用Obj()作为整数
int y = s.f5();//对象s使用f5()作为整数 cout << i << " " << j << " "//输出5和45
<< x << " " << y;//输出45和5 const ConstFun d;//const对象
int k = d.f5();//常量对象d只能调用常成员函数 cout << " k=" << k << endl;//输出5 system("pause");
}

例5.10

使用类对象数组和指针的例子。

 class Test
{
int num;
double f1;
public:
Test(int n)//一个参数的构造函数
{
num = n;
}
Test(int n, double f)//两个参数的构造函数
{
num = n;
f1 = f;
}
int GetNum()
{
return num;
}
double GetF()
{
return f1;
}
}; #include <iostream> using namespace std; void main()
{
Test one[] = { , }, *p;
Test two[] = { Test(,3.2),Test(,9.5) }; for (int i = ; i < ; i++)//输出对象数组对象
{
cout << "one[" << i << "]=" << one[i].GetNum() << endl;
} p = two;//使用指针输出对象数组元素 for (int i = ; i < ; i++, p++)
{
cout << "tow[" << i << "]=(" << p->GetNum() << ","
<< p->GetF() << ")" << endl;
} system("pause");
}

例5.11

仍然使用类Test,但改用对象指针数组的演示主程序。

 class Test
{
int num;
double f1;
public:
Test(int n)//一个参数的构造函数
{
num = n;
}
Test(int n, double f)//两个参数的构造函数
{
num = n;
f1 = f;
}
int GetNum()
{
return num;
}
double GetF()
{
return f1;
}
}; #include <iostream> using namespace std; void main()
{
Test *one[] = { new Test(),new Test() };
Test *two[] = { new Test(,3.2),new Test(,9.5) }; for (int i = ; i < ; i++)//输出对象数组对象
{
cout << "one[" << i << "]=" << one[i]->GetNum() << endl;
} for (int i = ; i < ; i++)
{
cout << "tow[" << i << "]=(" << two[i]->GetNum() << ","
<< two[i]->GetF() << ")" << endl;
} system("pause");
}

求解一元二次方程

头文件

equation.h

源文件

equation.cpp

源文件

Find.cpp

头文件

equation.h

 #if ! defined(EQUATION_H)
#define EQUATION_H
#include<iostream>
#include<cmath>
using namespace std;
//***************************
//* 先声明FindRoot类 *
//***************************
class FindRoot
{
private:
float a, b, c, d;
double x1, x2;
public:
FindRoot(float x, float y, float z);
void Find();
void Display();
};
#endif

源文件

equation.cpp

 #include"equation.h"
//***************************
//* 实现FindRoot类 *
//***************************
FindRoot::FindRoot(float x, float y, float z)//构造函数
{
a = x;
b = y;
c = z;
d = b*b - * a*c;
} void FindRoot::Find()//实现成员函数Find
{
if (d > )
{
x1 = (-b + sqrt(d)) / ( * a);
x2 = (-b - sqrt(d)) / ( * a);
return;
}
else if (d == )
{
x1 = x2 = (-b) / ( * a);
return;
}
else
{
x1 = (-b) / ( * a);
x2 = sqrt(-d) / ( * a);
}
} void FindRoot::Display()//实现成员函数Display
{
if (d > )
{
cout << "X1=" << x1 << "\nX2" << x2 << endl;
return;
}
else if (d == )
{
cout << "X1=X2=" << x1 << endl;
return;
}
else
{
cout << "X1=" << x1 << "+" << x2 << "i" << endl;
cout << "X2=" << x1 << "-" << x2 << "i" << endl;
}
}

源文件

Find.cpp

 #include"equation.h"

 void Read(float&, float&, float&);//参数使用对象引用方式

 void main()
{
float a, b, c; cout << "这是一个求方程ax2+bx+c=0的根的程序。" << endl; for (;;)//循环求解
{
Read(a, b, c);//准备系数 if (a == )//根据输入系数a决定是否结束for循环
{
return;
} FindRoot obj(a, b, c);//建立对象obj obj.Find();//求解
obj.Display();//输出计算结果
}//endfor
} void Read(float& a, float& b, float& c)//准备系数
{
cout << "输入方程系数a:"; cin >> a; if (a == )//系数a为零,则退出Read函数
{
getchar();//为了消除回车的影响
return;//将a=0返给for循环并退出Read函数
} cout << "输入方程系数b:";
cin >> b; cout << "输入方程系数c:";
cin >> c;
}