我们经常会看到一个类中可能会出现另一个类的对象作为它的数据成员,既然是对象,那么就会涉及到这个对象成员要初始化的问题。而程序中各种数据的共享,在一定程度上破环了数据的安全性。C++中有什么方法可以保证数据共享又防止数据改动。另外除以上两个问题,我还将说说C++的多文件程序。
1.我们在创建类的对象时,如果这个类具有内嵌的对象,那么该对象成员也将被自动创建。所以创建对象时既要对本类的基本数据成员初始化,又要对内嵌的对象初始化。具体怎么做呢,我还是用Employee(雇员)和Salary(薪水)两个类来举个实例:
1 #include "stdafx.h"
2 #include
3 #include
4
5 class Employee
6 {
7 private:
8 std::string id;
9 std::string name;
10 public:
11 Employee(std::string id,std::string name);
12 ~Employee();
13 void showEmployee();
14 };
15
16 Employee::Employee(std::string id,std::string name):id(id),name(name)
17 {
18 std::cout<<"构造对象employee"< 19 } 20 21 Employee::~Employee() 22 { 23 std::cout<<"释放对象employee内存空间"< 24 } 25 26 void Employee::showEmployee() 27 { 28 std::cout<<"编号:"< 29 std::cout<<"姓名:"< 30 } 31 32 33 class Salary 34 { 35 private: 36 Employee employee; //雇员 37 double wage;//工资 38 double bonus;//奖金 39 double commission;//提成 40 double allowance;//津贴 41 double subsidy;//补贴 42 public: 43 Salary(double wage,double bonus,double commission,double allowance,double subsidy,std::string id,std::string name); 44 ~Salary(); 45 void showSalary(); 46 }; 47 48 Salary::Salary(double wage,double bonus,double commission,double allowance,double subsidy,std::string id,std::string name):wage(wage),bonus(bonus),commission(commission),allowance(allowance),subsidy(subsidy),employee(id,name)//初始化对象成员employee 49 { 50 std::cout<<"构造对象salary"< 51 } 52 53 Salary::~Salary() 54 { 55 std::cout<<"释放对象salary内存空间"< 56 } 57 58 void Salary::showSalary() 59 { 60 employee.showEmployee();//显示雇员信息 61 std::cout<<"薪水:"< 62 std::cout<<" 工资:"< 63 std::cout<<" 奖金:"< 64 std::cout<<" 提成:"< 65 std::cout<<" 补贴:"< 66 std::cout<<" 津贴:"< 67 } 68 69 70 int main() 71 { 72 { 73 Salary salary(3000,3000,0,200,100,"001","aaa"); 74 salary.showSalary(); 75 } 76 77 return 0; 78 } 结果: 从初始化成员对象的代码中可以看到其实和之前所说的成员初始化表对数据成员初始化的形式是一样的。看到main函数体里的实现部分,可能有人会问那个大括号是否画蛇添足了。如果单单是从程序运行的流程考虑,的确没什么必要。而我特意加上这个大括号是为了说明在系统编译运行时它的顺序是怎么样的,从显示的结果来看,是先调用了Employee()的构造函数,在调用自己(Salary())的构造函数,而在调用各自的析构函数时则刚好相反。也许有人会问,那如果Salary里的对象成员不只一个,那么这些对象成员的构造函数调用的顺序是怎么样的?其实系统编译运行时对对象成员的构造函数调用的顺序是根据其在类声明中的顺序来依次调用,而释放对象空间(析构函数)的过程则刚好相反; 2.C++的常类型的引入,就是为了既保证数据共享又防止数据被改动。在面向对象里常类型主要有常对象、常数据成员以及常成员函数。(1)常对象的形式有:类名const 对象名[参数表]或const 类名 对象名[参数表],常对象中的数据成员值在对象的整个对象的生存期内不能被改变,而且常对象不能调用普通成员函数,只能调用常成员函数。(2)常数据成员的形式其实和C++对C语言的非面向对象特性扩充(1)所讲到过的常量是一样,但要注意的是类里的常数据成员只能通过初始化列表对其进行初始化,其他函数都不能对其赋值;(3)常成员函数的形式:类型 函数名(参数表) const,const是函数类型的组成部分,所以在声明函数和定义函数时都要加关键字const;同样我们以Employee(雇员)类为例: 1 #include "stdafx.h" 2 #include 3 #include 4 5 class Employee 6 { 7 private: 8 const std::string id;//常数据成员 9 const std::string name;//常数据成员 10 public: 11 Employee(std::string id,std::string name); 12 ~Employee(); 13 void showEmployee();//普通成员函数 14 void showEmployee() const;//常成员函数 15 }; 16 17 Employee::Employee(std::string id,std::string name):id(id),name(name) 18 { 19 //std::cout<<"构造对象employee"< 20 } 21 22 Employee::~Employee() 23 { 24 //std::cout<<"释放对象employee内存空间"< 25 } 26 27 void Employee::showEmployee() 28 { 29 std::cout<<"普通成员函数:"< 30 std::cout<<"编号:"< 31 