面向对象——对象成员

对象成员

面向对象“类成员”的分类

定义:面向对象“类”中的数据成员和函数成员统称为“类成员”;
函数成员可细分为:
在这里插入图片描述
数据成员依‘存储特征’可分为:
在这里插入图片描述
数据成员依‘数据类型’可分为:
在这里插入图片描述

类数据成员

普通数据成员

数据成员不能在确定对象之前存在,即实例化之后才存在;
如“int a”,只有在用类型定义(创建)一个变量时才分配空间;

常量数据成员

声明:在类数据成员声明之前添加添加关键字**“const”,** 即把数据成员声明为“常量数据成员”,如下所示:
class X{
const 类型 常量成员名;
……
}
常量数据成员的初始化可以通过构造函数初始化参数列表

静态数据成员

声明:在类数据成员声明之前添加添加关键字**“static”,** 即把数据成员声明为“静态数据成员”,如下所示:

class  X{
    static  类型  静态成员名;
    ……
}

静态数据成员的常常在类外定义,有2方式:
使用默认值的方式: 类型 类名::静态成员名;
指定初始值的方式:类型 类名::静态成员名=初始值;
注意事项:
① 在类外定义静态数据成员时,不能加上static限定词;
② 在定义静态数据成员时可以为其指定初始值(第2种形式),若定义时没有指定初值,系统默认初始值为0。

类对象成员

基本概念

类的数据成员一般都是基本数据类型,但也可以是结构、数据、枚举之类的自定义数据类型,还可以是其他类的对象
如果用其他类的对象作为类的成员,则称之为对象成员。
类对象作成员的形式如下:

class X{
	类名1  成员名1;
	类名2  成员名2;
		……
	类名n  成员名n;
};

类对象成员的初始化

可通过构造函数初始化列表中初始化对象成员
包含对象成员类的构造函数的定义形式:

X::X(参数表0): 成员名1(参数表1), ……, 成员名n(参数表n)
//初始化参数列表方式
{
	构造函数体;
}

对象成员的构造次序与它们在类中的声明次序相同,与它们在构造函数初始化列表中的次序无关!

class A{
    int a;
public:
    A(int i=1)  :a(i) { cout<<"constructing A:" <<a<<endl;    }
};
class B{
    int b;
public:
    B(int i) :b(i) {  cout<<"constructing B:" <<b<<endl;    }
};
class C{
    A a1,a2;
    B b1,b2;
public:
    C(int i2,int i3,int i4):b1(i2), b2(i3), a2(i4) { }
};
void main(){
    C x(2,3,4);
}

先声明a1,
再声明a2,
再声明b1,
再声明b2,
输出:
constructing A:1
constructing A:4
constructing B:2
constructing B:3

函数成员

声明与定义

函数成员的定义方式,有2种:
(1)在类声明中定义(内置定义 —>内置函数)

class X{……
public:
  返回类型 成员函数名(参数列表) {
       函数体(函数实现)
   }
};

类内定义的函数成员默认为内联函数!

(2)在类声明之外定义(外置定义—> 外置函数)

class X{……
public:
   返回类型 成员函数名(参数列表); //声明
};

返回类型 类名X::成员函数名(参数列表){
       函数体(函数实现)


类外定义的函数成员要成为内联函数, 需要手动声明!(inline关键字)

常量成员函数

常量成员函数
在类的成员函数说明后面可以加const关键字,则该成员函数成为常量成员函数。

class X{ ……
    const 类型 数据成员名;                                 //常量数据成员
	返回类型  函数名(参数列表) const;                //常量函数
	……
};

常量成员函数执行期间不应修改其所作用的对象。因此,在常量成员函数中不能修改成员变量的值
(静态成员变量除外),也不能调用同类的非常量成员函数(静态成员函数除外)。


class Sample
{
public:
int value;
void GetValue() const;
void func() { };
Sample() { }
};
void Sample::GetValue() const
{
value = 0; // wrong 常量成员函数不可修改其所作用的对象,故不可修改成员变量的值
func(); //wrong 常量成员函数不可修改其所作用的对象,故不可调用同类的非常量成员函数
}
 
int main() {
const Sample o;
o.value = 100; //err.常量对象不可被修改
o.func(); //err.常量对象上面不能执行非常量成员函数
o.GetValue(); //ok,常量对象上可以执行常量成员函数
return 0;
} //在Dev C++中,要为Sample类编写无参构造函数才可以,Visual Studio2010中不需要

只有类的成员函数才能定义为常量成员函数, 普通函数不能定义为常量函数。
(函数)常量参数 与 常量成员函数 两者是有区别的!
double distance(const int& p1); //常量参数
int fun(int t) const; //常量成员函数
前者可出现在任何函数中,而后者只适用于类成员函数
前者限制“函数对参数的修改”,而后者限制“类成员函数对类数据成员的修改”。

静态成员函数

  • 在类成员函数的原型前面加上“static”就将它定义成了静态成员函数。
    静态成员函数是属于整个类的!
    只能访问属于类的静态成员(包括静态数据成员和静态函数成员),
    不能访问非静态成员(包括非静态的数据成员和成员函数)。
  • 静态成员函数有两种调用方式
    类名::静态成员函数名(参数表);
    对象名.静态成员函数名(参数表);
#include <iostream>
using namespace std;

class Book{
private:
    char bkName[20];
    double price;
    static int number;                   //数目: 静态数据成员
    static double totalPrice;            //总价: 静态数据成员
public:
    Book(char *,double);                 //构造函数
    ~Book();
    double getPrice(){return price;}
    char * getName(){return bkName;}
    static int getNumber(){ return number;}
    static double getTotalPrice(){ return totalPrice;}
    void display();
};

Book::Book(char *name,double Price) {	//构造函数,可以访问静态和非静态成员
    strcpy(bkName,name);
    price=Price;
    number++; 
    totalPrice+=price;
}

Book::~Book(){ 
    number--;               //析构一本书就减少书的本数
    totalPrice -= price;    //析构一本书就减少书的总价 
}

/*此函数仅是一个验证,表示非静态成员函数可以访问静态的数据和函数成员*/
void Book::display(){
    cout<<"书名:"<<bkName<<",\t"<<"价格: "<<price<<endl;
    cout<<"总数:"<<number<<",\t"<<"总价: "<<totalPrice<<endl;
    cout<<"CALL static function: "<<getNumber()<<endl;
}

int Book::number=0; 				//定义并初始化静态数据成员
double Book::totalPrice=0;

void main(){
    Book b1("C++ 程序设计", 32.5);
    Book b2("数据库系统原理", 23);
    cout<<b1.getName()<<"\t"<<b1.getPrice()<<endl;		  //L1
    cout<<b2.getName()<<"\t"<<b2.getPrice()<<endl;		  //L2

    cout<<"总共: " <<b1.getNumber() <<" 本书,"<<"\t总价: " <<b1.getTotalPrice() <<" 元"<<endl;//L3

    {//块作用域
        Book b3("数据库系统原理",23);
        cout<<"总共: " <<b1.getNumber()<<" 本书,"<<"\t总价: "<<b1.getTotalPrice()<<" 元"<<endl; //L4
    }//b3生存期结束

    cout<<"总共: " <<Book::getNumber() <<" 本书,"<<"\t总价: "<<Book::getTotalPrice()<<" 元"<<endl;

    b2.display();
}

① 同普通成员函数一样,静态成员函数也可以在类内或类外定义,还可以定义成内联函数;

② 在类外定义静态成员函数时,不能加上static限定词。

③ 静态函数只能访问静态成员(包括静态的数据成员和成员函数),不能访问非静态成员。

④ 静态成员函数可以在定义类的任何对象之前被调用,非静态成员只有在实例化对象之后通过对象才能访问。


版权声明:本文为olivia12344321原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。