C++面向对象(一)——类及对象基础

C++面向对象(一)——类及对象基础

C++是一种面向对象(OOP)的语言,强调抽象、封装、多态、继承、可重用性等,类(class)是组成OOP的重要特性。

类的类型定义

class关键字一个类。

class 类名{
访问控制符:
    //成员
};

成员可以为成员变量、成员函数等。一般地,将类的成员函数称为类的方法

类似于结构体,在创建类的类型定义时不会为成员分配内存;仅当对象(类的变量)被定义时才会被分配内存。

访问控制标签

访问控制标签限定了外部(位于该类之外)对类成员的可访问性,限定范围为从该标签至下个标签间的所有成员。

  • public:成员可被外部访问。
  • private:默认标签,成员不可被外部访问,仅可被内部方法和友元函数访问。若成员未被指定标签,则其默认为private
  • protected:成员不可被外部访问,仅可被内部方法和派生类访问。

C++扩展了结构体,使其大多数功能类似于类。唯一不同之处在于,class默认标签为privatestruct默认标签为public

对象的定义

对象是类的变量,指类的实例,定义对象方法类与定义结构体变量一致。

  • 创建类的类型时定义对象:

    int n;
    class temp{
        //member
    }t[n];
    
  • 先创建类的类型再定义对象:

    int n;
    class temp{
       	//member
    };
    temp t[n];
    

对象各自有有自己的数据,但共享一组方法。

成员的访问

类似于结构体。

  • 直接访问运算符.:作用于对象上,通过对象名.成员进行访问。例:

    class temp{
    public:
        int a;
        void fun(int a){
            this->a=a;
        }
    };
    temp t;
    
    t.x;//访问变量
    t.sum(1,2);//访问方法
    
  • 间接访问运算符->:作用于对象指针上,通过对象指针名->成员进行访问。典例为通过this指针访问本类中的对象。

  • 域解析运算符:::用于访问命名空间中的成员。在类中,其为访问静态变量成员,或先声明后定义的方法中对方法的定义中,通过类名::方法以标识该方法来自的类。

方法的实现

  • 边声明边定义:

    class temp{
        int a;
    public:
        void fun(int a){
            this->a=a;
        }
    };
    
  • 先声明后定义:定义时需使用作用域解析运算符(::)以标识函数所属的类,即类名::函数名(形参表)

    class temp{
        int a;
    public:
        void fun(int);
    };
    void temp::fun(int a){
        this->a=a;
    }
    

构造函数

专门用于初始化类中成员变量的函数,其与类名同名,没有返回值,且必须被public标签修饰。

当类无构造函数时,编译器会自动为对象创建空的构造函数。

构造函数可使用默认参数。若定义了构造函数,则在定义对象时必须调用构造函数,为无默认参数的其他形参提供实参。

  • 边声明边定义

    class temp{
        int a;
    public:
        temp(int a){
            this->a=a;
        }
    };
    
  • 先声明后定义

    class temp{
       int a;
    public:
        temp(int);
    };
    temp::temp(int a){
        this->a=a;
    }
    
  • 定义对象:定义对象时必须调用构造函数,为无默认参数的其他形参提供实参。

    temp t(10);//隐式调用
    temp t=temp(10);//显式调用
    
  • 构造函数的初始化列表:

    class temp{
        int a,b;
    public:
        temp(int x,int y):a(x),b(y){ }//在形参表后 成员变量名(形参名),表示将形参赋值给成员变量
    };
    

析构函数

专门用于销毁成员的函数(如经过动态分配内存得到的成员变量),其名为~类名,没有返回值,且必须被public标签修饰。

若成员变量均为块作用域的局部变量,其将被自动销毁释放,无需析构函数。

当类无析构函数时,编译器会自动为对象创建空的析构函数。

析构函数无需手动显式调用,编译器会在恰当时机自动隐式调用。

  • 边声明边定义

    class temp{
    public:
        int *a=NULL;
        temp(){
            a=new int;
        }
        ~temp(){
            delete a;
        }
    };
    
  • 先声明后定义

    class temp{
        int *a=NULL;
        temp();
        ~temp();
    };
    temp::temp(){
        a=new int;
    }
    temp::~temp(){
        delete a;
    }
    

注意:以上代码仅供构造函数与析构函数的示例,实际上其存在浅拷贝问题。请不要这么使用!

this指针

this指针是由编译器隐式定义的指向当前对象本身的指针,在方法中可用this指针访问成员,在解决变量命名冲突、继承和多态中尤为重要。

使用方法:this->成员

class temp{
    int a;
public:
	temp(int a){
        this->a=a;
    }    
};

对象数组

类名 对象名[对象个数];

若类具有构造函数,则必须使用初始化序列表,为每个对象调用构造函数。

类名 对象名[对象个数]={类名(实参表),类名(实参表),...};//按顺序对应每个对象

类作用域

类中成员都具有类作用域,因此不同类才能使用同名变量及方法,这也导致访问变量和方法时必须通过对象进行访问。

类模板

  • 类模板类型的定义:

    template<typename 泛型名1,typename 泛型名2,...>
    class 类名{
        //成员
    };
    

    此处<>中的内容称为模板参数(形参),定义了若干泛型,其中typename为关键字(也可替换为class)。泛型在定义后即可像常规数据类型使用,但定义的所有泛型必须全部使用。

  • 具有模板的类对象的创建:

    类名<类型名1,类型名2,...>对象名;
    类名<类型名1,类型名2,...>对象名(构造函数实参);//有构造函数
    

    此处<>中的内容称为模板参数(实参),用于指定传入的参数数据类型,编译器将根据传入的类型自动生成对应类型的类。

posted @ 2025-03-29 00:03  椰萝Yerosius  阅读(19)  评论(0)    收藏  举报