C++类与对象的进一步讨论(2)

转载自:http://www.cnblogs.com/CaiNiaoZJ/archive/2011/08/06/2129329.html

        我们经常会看到一个类中可能会出现另一个类的对象作为它的数据成员,既然是对象,那么就会涉及到这个对象成员要初始化的问题。而程序中各种数据的共享,在一定程度上破环了数据的安全性。C++中有什么方法可以保证数据共享又防止数据改动。另外除以上两个问题,我还将说说C++的多文件程序。

  1.我们在创建类的对象时,如果这个类具有内嵌的对象,那么该对象成员也将被自动创建。所以创建对象时既要对本类的基本数据成员初始化,又要对内嵌的对象初始化。具体怎么做呢,我还是用Employee(雇员)和Salary(薪水)两个类来举个实例:

#include "stdafx.h"
 #include<string>
 #include<iostream>
 
 class Employee
 {
 private:
         std::string id;
         std::string name;
 public:
         Employee(std::string id,std::string name);
 ~Employee();
 void showEmployee();
 };
 
 Employee::Employee(std::string id,std::string name):id(id),name(name)
 {
     std::cout<<"构造对象employee"<<std::endl;
 }
 
 Employee::~Employee()
 {
     std::cout<<"释放对象employee内存空间"<<std::endl;
 }
 
 void Employee::showEmployee()
 {
     std::cout<<"编号:"<<id<<std::endl; 
     std::cout<<"姓名:"<<name<<std::endl;
 }
 
 
 class Salary
 {
 private:
         Employee employee; //雇员
 double wage;//工资
 double bonus;//奖金
 double commission;//提成
 double allowance;//津贴
 double subsidy;//补贴
 public:
         Salary(double wage,double bonus,double commission,double allowance,double subsidy,std::string id,std::string name);
 ~Salary();
 void showSalary();
 };
 
 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
 {
     std::cout<<"构造对象salary"<<std::endl;
 }
 
 Salary::~Salary()
 {
     std::cout<<"释放对象salary内存空间"<<std::endl;
 }
 
 void Salary::showSalary()
 {
     employee.showEmployee();//显示雇员信息
     std::cout<<"薪水:"<<std::endl;
     std::cout<<"  工资:"<<wage<<std::endl;
     std::cout<<"  奖金:"<<bonus<<std::endl;
     std::cout<<"  提成:"<<commission<<std::endl;
     std::cout<<"  补贴:"<<subsidy<<std::endl;
     std::cout<<"  津贴:"<<allowance<<std::endl;
 }
 
 
 int main()
 {
     {
         Salary salary(3000,3000,0,200,100,"001","aaa");
         salary.showSalary();
     }
 
 return0;
 }

结果:

从初始化成员对象的代码中可以看到其实和之前所说的成员初始化表对数据成员初始化的形式是一样的。看到main函数体里的实现部分,可能有人会问那个大括号是否画蛇添足了。如果单单是从程序运行的流程考虑,的确没什么必要。而我特意加上这个大括号是为了说明在系统编译运行时它的顺序是怎么样的,从显示的结果来看,是先调用了Employee()的构造函数,在调用自己(Salary())的构造函数,而在调用各自的析构函数时则刚好相反。也许有人会问,那如果Salary里的对象成员不只一个,那么这些对象成员的构造函数调用的顺序是怎么样的?其实系统编译运行时对对象成员的构造函数调用的顺序是根据其在类声明中的顺序来依次调用,而释放对象空间(析构函数)的过程则刚好相反;

  2.C++的常类型的引入,就是为了既保证数据共享又防止数据被改动。在面向对象里常类型主要有常对象、常数据成员以及常成员函数。(1)常对象的形式有:类名 const 对象名[参数表]或const 类名 对象名[参数表],常对象中的数据成员值在对象的整个对象的生存期内不能被改变,而且常对象不能调用普通成员函数,只能调用常成员函数。(2)常数据成员的形式其实和C++对C语言的非面向对象特性扩充(1)所讲到过的常量是一样,但要注意的是类里的常数据成员只能通过初始化列表对其进行初始化,其他函数都不能对其赋值;(3)常成员函数的形式:类型 函数名(参数表) const,const是函数类型的组成部分,所以在声明函数和定义函数时都要加关键字const;同样我们以Employee(雇员)类为例:

#include "stdafx.h"
 #include<string>
 #include<iostream>
 
 class Employee
 {
 private:
 const std::string id;//常数据成员
 const std::string name;//常数据成员
 public:
         Employee(std::string id,std::string name);
 ~Employee();
 void showEmployee();//普通成员函数
 void showEmployee() const;//常成员函数
 };
 
 Employee::Employee(std::string id,std::string name):id(id),name(name)
 {
 //std::cout<<"构造对象employee"<<std::endl;
 }
 
 Employee::~Employee()
 {
 //std::cout<<"释放对象employee内存空间"<<std::endl;
 }
 
 void Employee::showEmployee()
 {
     std::cout<<"普通成员函数:"<<std::endl;
     std::cout<<"编号:"<<id<<std::endl; 
     std::cout<<"姓名:"<<name<<std::endl;
 }
 
 void Employee::showEmployee() const
 {
     std::cout<<"常成员函数:"<<std::endl;
     std::cout<<"编号:"<<id<<std::endl; 
     std::cout<<"姓名:"<<name<<std::endl;
 }
 
 int main()
 {
     Employee employee("001","aa");
     employee.showEmployee();
 
     std::cout<<"********************************"<<std::endl;
 
     Employee const const_employee("002","bb");//常对象
     const_employee.showEmployee();
 
 return0;
 }

结果:

从上述示例代码中,我可以看到两个同名函数void showEmployee(),一个是普通成员函数,一个是常成员函数,它们是重载的,由此说明const可以被用于对重载函数的区分;

  3.C++的源程序基本上由3个部分组成:类的声明部分、类的实现部分和类的使用部分,针对3个部分,C++中对应分为3个文件:类声明文件(*.h文件)、类的实现文件(*.cpp)和类的使用文件(*.cpp,主函数main文件)。那么为什么C++中的要使用多文件,一个*.cpp类的使用文件就可解决的问题,为何那么麻烦要分三步走呢?主要有以下几个方面:(1)类的实现文件通常会比较大,将类的声明和实现放在一起,不利于程序的阅读、管理和维护。我们通常说接口应该和实现的部分分离,这样可以更易于修改程序。(2)把类成员函数的实现放在声明文件中和单独放实现文件里,在编译时是不一样的。前者是作为类的内联函数来处理的。(3)对于软件的厂商来说,它只需向用户提供程序公开的接口,而不用公开程序源代码。从这一点来看,我觉得C++在面向对象方面比C#更加明确,清晰。

  4.最后还是一样,我将用一个示例来总结一下今天所讲的内容,同时将把程序按照C++多文件的原则分成3个文件来实现(开发工具:vs2010):

1.声明文件*.h:

 employee.h(雇员类的声明文件)

View Code 
 #include<string>
 #include<iostream>
 
 class Employee
 {
 private:
 const std::string id;//常数据成员
 const std::string name;//常数据成员
 public:
         Employee(std::string id,std::string name);
 ~Employee();
 void showEmployee();//普通成员函数
 void showEmployee() const;//常成员函数
 };

salary.h(薪水类的声明文件)

View Code 
 #include "employee.h"
 
 class Salary
 {
 private:
 const Employee employee; //雇员
 constdouble wage;//工资(常数据成员)
 double bonus;//奖金
 double commission;//提成
 double allowance;//津贴
 double subsidy;//补贴
 public:
         Salary(double wage,double bonus,double commission,double allowance,double subsidy,std::string id,std::string name);
 ~Salary();
 void showSalary();
 };

2.实现文件*.cpp:

employee.cpp(雇员类的实现文件)

View Code 
 #include "stdafx.h"
 #include<iostream>
 
 #include "employee.h"
 
 Employee::Employee(std::string id,std::string name):id(id),name(name)
 {
     std::cout<<"构造对象employee"<<std::endl;
 }
 
 Employee::~Employee()
 {
     std::cout<<"释放对象employee内存空间"<<std::endl;
 }
 
 void Employee::showEmployee()
 {
     std::cout<<"普通成员函数:"<<std::endl;
     std::cout<<"编号:"<<id<<std::endl; 
     std::cout<<"姓名:"<<name<<std::endl;
 }
 
 void Employee::showEmployee() const
 {
     std::cout<<"常成员函数:"<<std::endl;
     std::cout<<"编号:"<<id<<std::endl; 
     std::cout<<"姓名:"<<name<<std::endl;
 }

salary.cpp(薪水类的实现文件)
View Code 
 #include "stdafx.h"
 #include<iostream>
 
 #include "salary.h"
 
 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)
 {
     std::cout<<"构造对象salary"<<std::endl;
 }
 
 Salary::~Salary()
 {
     std::cout<<"释放对象salary内存空间"<<std::endl;
 }
 
 void Salary::showSalary()
 {
     employee.showEmployee();//显示雇员信息
     std::cout<<"薪水:"<<std::endl;
     std::cout<<"  工资:"<<wage<<std::endl;
     std::cout<<"  奖金:"<<bonus<<std::endl;
     std::cout<<"  提成:"<<commission<<std::endl;
     std::cout<<"  补贴:"<<subsidy<<std::endl;
     std::cout<<"  津贴:"<<allowance<<std::endl;
 }

3.使用文件*.cpp

main主函数文件

#include "stdafx.h"
 #include<iostream>
 
 #include "salary.h"
 int main()
 {
     {
         Salary salary(3000,3000,0,200,100,"001","aaa");
         salary.showSalary();
     }
 
 return0;
 }

结果:



1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码
应用背景为变电站电力巡检,基于YOLO v4算法模型对常见电力巡检目标进行检测,并充分利用Ascend310提供的DVPP等硬件支持能力来完成流媒体的传输、处理等任务,并对系统性能做出一定的优化。.zip深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值