person.h

/**************************************
 在此处进行成员属性、函数声明

  自动生成4个
  1、无参构造函数   对private成员初始化
  2、析构函数        内存泄漏
  3、拷贝构造函数   深度赋值
  4、=运算符重载    深度赋值
**************************************/

#ifndef _person
#define _person

class Cat{
public:
    void F();
};

class person{//抽象性
private://封装性
    //const int id;  //const id=1;// error c++不允许直接赋值 只允许在构造函数中赋值
    int m_id;
    char* m_name;
public:  
    static void PrintName(person * temp);
    //inline  成员函数默认都是内联函数 可以不加 inline
    void PrintName();
    //得到函数的地址
    void getAddress();
    int getM_id();
    /*
        运算符重载:
    */
    void operator=(person& temp){
        this->m_id=temp.m_id;
        //重新分配空间 深度赋值
        this->m_name=new char[10];
        strcpy(this->m_name, temp.m_name);
        cout<<"运算符重载"<<endl;
    }
public:
    int GetId();
    /*
    explicit
    放在构造函数前面:
        表示在 实例化 赋值的时候不能隐形转化
        比如: person onePerson=1;
               person onePerson(1);
        加了 explicit 就只会把 1 当成int
        不加  如果没有 构造函数只有一个参数是int的
        只有 一个参数是char * 型的 那么就会找该构造函数实例化
        此时就会把 1 隐形转化
        避免隐形转化在构造函数前加 explicit
    */
    
    /*
        拷贝构造函数
    */
    explicit person(person& temp){
        this->m_id=temp.m_id;
        //重新分配空间 深度赋值
        this->m_name=new char[10];
        strcpy(this->m_name, temp.m_name);
        cout<<"拷贝构造函数"<<endl;
    }

    /*
    构造函数
        1、没有返回值
        2、函数名和类名一样
        3、参数和传统函数一样
    */
    explicit person();
    explicit person(int id, char* name);
    explicit person(char* name);
    /*
    析构函数
        1、在对象销毁时调用
        2、作用,释放内存,等
    */
    ~person();

    /*
----------------
  友元:
----------------
1、如果希望一个普通函数F中能够访问类C中的
非公有成员,可以在类C中声明普通函数F为类C的友元
    class C{
        //注意这个函数是全局函数 没有定义C中
        friend void F();
    };

    void F(){
        //该函数可以访问类C非公有的成员
    }

2、如果希望类C2的成员函数C2::F可以访问类C1的非公有成员
可以在类C1中将类C2的成员函数C2 F声明为友元
    class C2{
        void F(){
            //该函数可以访问类C非公有的成员
        }
    };

    class C1{
        friend void C2::F();
    };

3、如果希望类C2的【所有成员函数】可以访问类C1的非公有成员
可以在类C1中将类C2的成员函数C2声明为友元
    class C2{
            //所有函数可以访问类C1非公有的成员
        void F(){
        
        }
    };

    class C1{
        //类C2可以访问类C1的非公有成员
        friend void C2;
    };
    */
    friend void test();
    friend void Cat::F();

}; //注意此处的;  和c语言的struct{};  可以进行比较

#endif _person

person.cpp

#include <string.h>
#include <iostream>
using namespace std;
#include "person.h"

/*
在此处进行函数的实现
*/

//静态函数  
//调用方式: 类名::函数()
/*
声明:    static void PrintName(person temp);
注意实现的时候就不需要加 static
*/  
void person::PrintName(person * temp){
    cout<<"temp.m_name="<<temp->m_name<<endl;
}
//this指向当前实例  
//用法: this->属性名
void person::PrintName(){
    cout<<"this->m_name="<<this->m_name<<endl;
}

void person::getAddress(){
    cout<<"this="<<this<<endl;
}

int person::getM_id(){
    return this->m_id;
}

//:id(1)  初始化常量
/*
    此种方法: 构造函数名():属性名1(值1), 属性名2(值2)...
    可以用于初始化常量,并且常量只能用此方法初始化
    也可以初始化成员变量
    此种方式不能初始化字符串
*/
person::person()//:id(1)
{
    this->m_id=122;
    /*
    注意事项:
        new 分配的内存 被所有person类型的 对象 所共享  
        只要有一个person类型的对象delete new分配的内存后
        其它person类型的对象也就不能访问该内存了
    */
    this->m_name = new char[10];
    strcpy(m_name, "tangtao");
}

person::person(int id, char* name)//:id(id) //可以通过参数初始化const
{
    //this->id = 1;
    this->m_id = id;
    this->m_name = new char[10];
    strcpy(this->m_name, name);
}

person::person(char* name){
    this->m_name = new char[10];
    strcpy(this->m_name, name);
}

//释放内存 防止内存泄漏
person::~person(){
    cout<<"delete............"<<endl;
    if(this->m_name!=NULL){
        delete this->m_name;
        this->m_name = NULL;
    }
}

int person::GetId()
{
    return this->m_id;
}

void Cat::F(){
    person onePerson(12, "tangtao");
    cout<<"类2访问类1的非共有的成员=="<<onePerson.m_name<<endl;
}

 

Test.cpp

#include <iostream>
using namespace std;
#include "person.h"
#include <stdio.h>
#include "person.h"
/*
类是对象的抽象
对象是类的具体实现
*/
/*class person{//抽象性
private://封装性
    int m_id;
public:
    char m_name[10];
    //静态函数  
    //调用方式: 类名::函数()   
    static void PrintName(person temp){
        cout<<"temp.m_name="<<temp.m_name<<endl;
    }
    //this指向当前实例  
    //用法: this->属性名
    void PrintName(){
        cout<<"this.m_name="<<this->m_name<<endl;
    }

}; //注意此处的;  和c语言的struct{};  可以进行比较




int main(){
    person onePerson={1, "tangtao"}; //什么是实例化 分配内存的过程,也就是对象
    //onePerson.m_id=12; //private
    strcpy(onePerson.m_name, "itao");
    //PrintName(onePerson);
    //onePerson.PrintName();
    person::PrintName(onePerson);
    onePerson.PrintName();
    cout<<onePerson.m_name<<endl;
    return 0;
}
*/


int test1(){
    //person onePerson; //无参的构造函数实例化对象
    //什么是实例化 分配内存的过程,也就是对象
    person onePerson(21, "itao");
    //实例化有参数的构造函数
    //onePerson.m_id=12; //private
    //strcpy(onePerson.m_name, "itao");
    //PrintName(onePerson);
    //onePerson.PrintName();
    //person::PrintName(&onePerson);
    //onePerson.PrintName();
    //cout<<"m_);
    //cout<<onePerson.GetId()<<endl;
    //test();
    Cat oneCat;
    oneCat.F();

    return 0;
}

 

 

相关文章: