IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++面向对象程序设计(二) -> 正文阅读

[C++知识库]C++面向对象程序设计(二)

C++面向对象程序设计(二)

二、类和对象基础

1.类和对象的基本概念

在类的定义中,用下列访问范围关键字来说明类成员可被访问范围:

  • private:私有成员,只能在成员函数内访问
  • public:共有成员,可以在任何地方访问
  • protected:保护成员

以上三种关键字出现的次数和先后次序都没有限制。

  • 定义一个类
class claaName{
  private:私有属性和函数
  public:共有属性和函数
  protected:保护属性和函数
};

如果某个成员前面没有上述关键字,则缺省地被认为是私有成员。

class Man{
  int nAge;
  char szName[20];
  public:
  void SetName(char * szName){
    strcpy(Man::szName,szName);
  }
};
  • 类成员的可访问范围

    在类的成员函数内部,能够访问:

    • 当前对象的全部属性和函数

    • 同类其他对象的全部属性和函数

    在类的成员函数以外的地方,只能够访问该类对象的公有成员

class CEmployee{
  private:
  char szName[30];
  public:
  int salary;
  void setName(char * name);
  void getName(char * name);
  void averageSalary(CEmployee e1,CEmployee e2);
};
void CElemployee::setName(char * name){
  strcpy(szName,name);
}
void CEmployee::getName(char * name){
  strcpy(name,szName);
}
void CEmployee::averageSalary(CEmployee e1,Cemployee e2){
  cout<<e1.szName;//ok,访问同类其它对象私有成员
  salary=(e1.salary+e2.salary)/2;
}
int main(){
  CEmployee e;
  strcpy(e.szName,"Tom123456789");//编译出错,不能访问私有成员
  strcpy("Tom");//ok
  e.salary=5000;//ok
  return 0;
}

“隐藏”的作用

如果将上面的程序移植到内存空间紧张的手持设备上,希望将szName改为 char szName[5],若szName不是私有,那么就要找出所有类似strcpy(e.szName,“Tom123456789”);这样的语句进行修改,以防数组越界,这样做会很麻烦。

如果将szName变为私有,那么程序中就不可能出现(除非在类的内部)strcpy(e.szName,“Tom123456789”); 这样的语句,所有对szName 的访问都是通过成员函数来进行,比如:e.setName(“Tom123456789”);

那么就算szName改短了,上面的语句也不需要找出来修改,只要改setName成员函数,在里面确保不越界就可以了。

  • 用struct定义类
struct CEmployee {
  char szName[30];//公有
  public:
  int salary;
  void setName(char * name);
  void getName(char * name);
  void averageSalary(CEmployee e1,CEmployee e2);
};

和用class的唯一区别,就是未说明公有还是私有的成员,就是公有。

  • 成员函数的重载及参数缺省

成员函数也可以重载(注意避免二义性的产生)

成员函数可以带缺省参数(给定默认值)

#include <iostream>
using namespace std;
class Location{
  private:
  int x,y;
  public:
  void init(int x=0,int y=0);
  void valueX(int val){x=val;}
  int valueX(){return x;}
};
void Location::init(int X,int Y){
  x=X;
  y=Y;
}
int main(){
  Location A,B;
  A.init(5);
  A.valueX(5);
  cout<<A.valueX();//输出 5
  return 0;
}
class Location{
  private:
  int x,y;
  public:
  void init(int x=0,int y=0);
  void valueX(int val=0){x=val;}
  int valueX(){return x;}
};
Location A;
A.valueX();//错误,编译器无法判断调用哪一个valueX

2.构造函数

成员函数的一种

  1. 名字与类名相同,可以有参数,不能有返回值(void也不行)

  2. 作用是对对象进行初始化,如给成员变量赋初值

  3. 如果定义类时没有写构造函数,则编译器生成一个默认的无参数的构造函数

    默认构造函数无参数,不做任何操作

  4. 如果定义了构造函数,则编译器不生成默认的无参数的构造函数

  5. 对象生成时构造函数自动被调用。对象一旦生成,就再也不能在其上执行构造函数。

  6. 一个类可以有多个构造函数

为什么需要有构造函数:

(1)构造函数执行必要的初始化工作,有了构造函数,就不必专门再写初始化函数,也不用担心忘记调用初始化函数。

(2)有时对象没有被初始化就使用,会导致程序出错

class Complex{
  private:
  double real,imag;
  public:
  void Set(double r,double i);
};//编译器自动生成默认构造函数
Complex c1;//默认构造函数被调用
Complex *pc=new Complex;//默认构造函数被调用
class Complex{
  private:
  double real,imag;
  public:
  Complex(double r,double i=0);
}
Complex::Complex(double r,double i){
  real=r;imag=i;
}
Complex c1;//错误,缺少构造函数的参数
Complex *pc=new Complex;//错误,缺少参数
Complex c1(2);//正确,调用第一个
Complex c1(2,4),c2(3,5);
Complex *pc=new Complex(3,4);

可以有多个构造函数,参数个数或类型不同

class Complex{
  private:double real,imag;
  public:
  void Set(double r,double i);
  Complex(double r,double i);
  Complex(double r);
  Complex(Complex c1,Complex c2);
};
Complex::Complex(double r,double i){
  real=r;imag=i;
}
Complex::Complex(double r){
  real=r;imag=0;
}
Complex::Complex(Complex c1,Complex c2){
  real=c1.real+c2.real;
  imag=c1.imag+c2.imag;
}
Complex c1(3),c2(1,0),c3(c1,c2);

构造函数最好是public的,private构造函数不能直接用来初始化对象

class CSample{
  private:CSample(){
  }
};
int main(){
  CSample Obj;//错误,唯一的构造函数是private
  return 0;
}

习题:

有类A如下定义:

class A{
  int v;
  public:
  A(int n){v=n;}
};
//下面哪条语句编译不会出错?
A a1(3);			 //正确
A a2;					 //错误
A * p=new A(); //错误
  • 构造函数在数组中国的使用
class CSample{
  int x;
  public:
  CSample(){
    cout<<"Constructor 1 called"<<endl;
  }
  CSample(int n){
    x=n;
    cout<<"Constructor 2 called"<<endl;
  }
};
int main(){
  CSample array1[2];			//constructor 1 called
 												  //constructor 1 called
  cout<<"step1"<<endl;  	//step 1
  CSample array2[2]={4,5};//constructor 2 called
  												//constructor 2 called
  cout<<"step2"<<endl;		//step2
  CSample array3[2]={3};	//constructor 2 called
  												//constructor 1 called
  cout<<"step3"<<endl;		//step3
  CSample * array4=new CSample[2];
  												//constructor 1 called
  												//constructor 1 called
  delete [] array4;
  return 0;
}
  • 构造函数在数组中的使用
class Test{
  public:
    Test(int n){}	(1)
    Test(int n,int m){} (2)
    Test(){}	(3)
};
Test array1[3]={1,Test(1,2)};//分别用(1)(2)(3)初始化
Test array2[3]={Test(2,3),Test(1,2),1};//分别用(2)(2)(1)初始化
Test *p Array[3]={new Test(4),new Test(1,2)};//前两个分别用(1),(2)初始化,后一个未初始化

习题:

假设A是一个类的名字,下面的语句生成了几个类A的对象?

A * arr[4]={new A(),NULL,new A()};

答案:两个

只有在建立对象的时候,才会初始化,NULL没有调用构造函数,不等于调用无参数构造函数,只是给A*类型指针赋值NULL。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-09-08 10:29:29  更:2021-09-08 10:31:20 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 20:09:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码