面相对象编程

#include "basic.h"

int month = 1;
int day = 3;

class Date {
public:
    void Set(int m, int d, int y){
        month = m, day = d, year = y;
    }

    int IsLeapYear(){
        return (year % 4 == 0 && year % 100 == 0);
    }

    void Print() const{
        cout<<month<<"/"<<day<<"/"<<year<<endl;
    }

    int IsBirthday();

private:
    int month;
    int day;
    int year;
};

void PrintLeapYear(Date* day){
    day->Print();
    if (day->IsLeapYear()){
        printf("yes\n");
    } else{
        printf("no\n");
    }

}

void PrintLeapYear_Ref(Date& day){
    day.Print();
    if (day.IsLeapYear()){
        printf("yes\n");
    } else{
        printf("no\n");
    }
}


int Date::IsBirthday() {
    if (this->month == ::month && this->day == ::day) {
        return 1;
    } else
        return 0;
}

int main(){
    Date today;
    today.Set(2,8,1998);
    today.Print();
    PrintLeapYear(&today);
    PrintLeapYear_Ref(today);
    cout<<today.IsBirthday()<<endl;
}

结构与类

在C++中,结构(struct)和类(class)都是用户定义的复合数据类型,用于封装数据和功能。

  1. 成员访问权限

    • 结构(struct)

      • 在结构中,成员默认是公共的(public),也就是说,所有成员可以从外部访问。
      • 这意味着结构的数据成员对外是可见的,并且可以直接访问。
    • 类(class)

      • 在类中,成员默认是私有的(private),也就是说,除了类的成员函数之外,外部无法直接访问类的数据成员。
      • 这意味着类的数据成员对外是隐藏的,需要使用成员函数来访问或修改它们。
  2. 成员函数

    • 结构(struct)

      • 结构可以包含成员函数,但这些函数默认也是公共的,可以从外部访问。
      • 结构通常用于表示一组数据,而不是具有复杂的行为的对象。
    • 类(class)

      • 类通常包含成员函数,但这些函数默认是私有的,只有类的成员函数可以访问它们。
      • 类被用于封装数据和行为,允许实现数据隐藏和信息隐藏。
  3. 构造函数和析构函数

    • 结构(struct)

      • 结构可以有构造函数和析构函数,但它们通常较少用于结构。
    • 类(class)

      • 类经常使用构造函数和析构函数来初始化对象和清理资源,这使得它们更适合用于实现对象的生命周期管理。
  4. 继承

    • 结构(struct)

      • 结构可以继承其他结构,但不支持访问控制关键字(如 privateprotectedpublic)。
      • 结构继承通常用于实现数据复用。
    • 类(class)

      • 类支持继承,并可以使用访问控制关键字来控制派生类对基类成员的访问权限。
      • 类的继承通常用于实现面向对象的特性,如多态性。

结构更适合用于简单的数据组织,而类更适合用于实现数据封装、面向对象编程和复杂的行为。

成员函数与数据成员

定义成员函数

class Data{
public:
	void Set(int m, int d, int y){
		month = m;
		day = d;
		year = y;	
	}
}

也可以先声明再定义

class Data{
public:
	void Set(int m, int d, int y);
}



void Data::Set(int m, int d, int y){
		month = m;
		day = d;
		year = y;	
}

:: 作用域区分符,类名加在成员函数名之前而不是加在函数的返回类型前

调用成员函数

Date Today;
Today.Set(2,6,1998);
Today.Print();

也可以使用指针调用成员函数

void PrintLeapYear(Date* day){
    day->Print();
    if (day->IsLeapYear()){
        printf("yes");
    } else{
        printf("no");
    }

}

使用引用调用成员函数

void PrintLeapYear_Ref(Date& day){
    day.Print();
    if (day.IsLeapYear()){
        printf("yes");
    } else{
        printf("no");
    }
}

调用

int main(){
    Date today;
    today.Set(2,8,1998);
    today.Print();
    PrintLeapYear(&today);
    PrintLeapYear_Ref(today);
}

成员函数中访问成员无需对象名前缀,因为有隐含形参 this 指针

若调用类外同名变量需要加 ::

int month

void Date::Set(int m, int d, int y){
	::month = m; //调用的是类外month
	month = m; //调用的是类内month
}

保护成员

当访问控制说明符未声明时,默认为 private

当声明为 public 时,类的数据成员和函数成员是可以外部访问的,当声明为 protected 或者 private 时,类的数据成员和函数成员外部不可访问,只能内部访问

构造函数与祈构函数

构造函数在对象建立的时候自动执行

  • 构造函数与类名同名,但是前没有返回类型声明
  • 构造函数可以有参数
  • 当类中成员含有其它类时,初始化类需要在构造函数冒号后面
  • 常成员与引用成员初始化时也要放在构造函数冒号后面
  • 若未提供构造函数,C++ 将,默认提供一个无参数的构造函数
  • 当类指定了一个构造函数时,C++ 将不再提供默认构造函数
  • 构造函数可以被重构

祈构函数

  • 祈构函数为构造函数加 ~
  • 祈构函数在类的实例声明周期结束后执行

注意

C++ 变量初始化有两种形式

int m = 10;
int n(10);

在构造函数的冒号后面的类成员初始化不可使用第一中形式

赋值只有一种方法

m = 10;
n(20); //error

以下是一个示例

#include "basic.h"
#include <cstring>

class Attribute{
public:
    Attribute(int hp, int eng, int atk){
        HP = hp, Energy = eng, ATK = atk;
    }
    void get_atr() const{
        cout<<"HP: "<<HP<<endl;
        cout<<"ENERGY: "<<Energy<<endl;
        cout<<"ATK: "<<ATK<<endl;
    }

    void eng_drop(int num){
        Energy  = Energy - num;
    }

private:
    int HP;
    int Energy;
    int ATK;
};



class Mankind{
public:
    Mankind(char * pname, int id, int hp = 100, int eng = 100, int atk = 10): atr(hp, eng, atk), ID(id){
        cout<<pname<<" is created"<<endl;
        strncpy(name, pname, sizeof(name));
        name[sizeof(name)-1] = '\0';
    }

    void get_atr(){
        atr.get_atr();
    }

    void IsEmo(){
        cout<<name<<" is emo"<<endl;
        atr.eng_drop(50);
    }


    ~Mankind(){
        cout<<name<<" is :wq"<<endl;
    }
private:
    char name[10];
    int ID;
    Attribute atr;
};

int main(){
    Mankind me("Luke",1001,90,50,10);
    me.IsEmo();
    me.get_atr();
}

友元

  • 在类中成员函数前加 friend 可以在函数中访问该类的私有成员
  • 两个不同的类中定义同名的友元函数可以同时访问两个类的私有成员,用于特定情况下的数据共享

在C++中,友元(Friend)是一种机制,允许一个类或函数访问另一个类的私有成员(包括私有成员变量和私有成员函数)。友元在某些情况下非常有用,但也应该谨慎使用,因为它会降低类的封装性。

友元的使用方式有两种:友元函数和友元类。

  1. 友元函数:
    友元函数是一个独立的函数,被声明为某个类的友元,因此可以访问该类的私有成员。
class MyClass {
private:
    int privateVar;

public:
    MyClass(int val) : privateVar(val) {}

    // 友元函数声明
    friend void friendFunction(const MyClass& obj);
};

// 友元函数的定义
void friendFunction(const MyClass& obj) {
    // 可以访问MyClass的私有成员privateVar
    std::cout << "PrivateVar in friendFunction: " << obj.privateVar << std::endl;
}

int main() {
    MyClass myObject(42);
    friendFunction(myObject);
    return 0;
}
  1. 友元类:
    友元类是一个类,被声明为另一个类的友元,从而可以访问该类的私有成员。友元类通常用于建立两个类之间的特殊关系。以下是友元类的示例:
class FriendClass {
public:
    void accessPrivateVar(const MyClass& obj) {
        // 可以访问MyClass的私有成员privateVar
        std::cout << "PrivateVar in FriendClass: " << obj.privateVar << std::endl;
    }
};

class MyClass {
private:
    int privateVar;

    // 友元类声明
    friend class FriendClass;

public:
    MyClass(int val) : privateVar(val) {}
};

int main() {
    MyClass myObject(42);
    FriendClass friendObj;
    friendObj.accessPrivateVar(myObject);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值