C++学习笔记03

复习

  面向对象

    封装(写类),前提是抽象。从对象、行为/交互角度去考虑程序如何实现

    类定义:数据,函数,访问限制(public允许本类之外的函数也可以访问,private只允许本类的成员的函数访问),多文件,类实现放在.cpp文件,类定义里面的函数只声明(放在.h文件中#ifndef)

    构造函数:创建每一个对象时总会调用构造函数,可以重载。如果没有人为定义构造函数,编译器会自动产生一个无参构造函数

    this关键字:固定指向当前对象,只存在于成员函数中,对哪个对象调用这个成员函数的时候,this就指向哪个对象。*this就代表当前对象。

    静态成员:属于整个类的数据或者行为

      静态成员变量:所欲这个类的对象公用一份,在类的外面初始化,初始化时要在变量名前面用类名双冒号修饰。

      静态成员函数:所有这个类的对象的共同行为,不依赖于任何一个对象,因此静态成员函数中不存在this,只能访问静态成员,访问非静态成员必须要指明对象。

 

#include<iostream>
using namespace std;
#include<string>
//int thisyear;

class Person{
    string name;
    int year;
    bool gender;
    Person* lover;
public:
    static int thisyear;//静态成员
    Person(const string& name,bool gender){
        Person::name = name; 
        Person::gender = gender;
        year = thisyear;
        lover = NULL;
    }
    void show(){
        cout<<"我是"<<(gender?"帅哥":"美女")<<name<<",今年"<<thisyear-year<<"";
        if(lover)
            cout<<",跟"<<lover->name<<"恋爱中"<<endl;
        else
            cout<<",单身"<<endl;
    }
    void Love(Person* x){
    //Person* const this接受隐含参数指向当前对象
    Person::lover = x;
    x->lover = this;
    }
    void Leave(){
        lover = lover->lover=NULL;
    }
    static void timefly(int y){//静态成员函数 不存在this只能访问静态成员
        thisyear = y;
    }
        
};
int Person::thisyear = 1990;//静态成员变量初始化,前面加类型 int 

int main()
{
    Person::timefly(1990);
    Person a("李钊",true);
    Person::timefly(1992);
    Person b("芙蓉",false);
    Person::timefly(2013);
    a.show();//传递隐含参数 a.show(&a)
    b.show();
    Person::timefly(2015);
    a.Love(&b);
    a.show();
    b.show();
    Person::timefly(2016);
    a.Leave();
    a.show();
    b.show();
    system("pause");
    return 0;
}

单例模式

    通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。

    以下例子通过将构造函数私有来防止实例化新的对象:

#include<iostream>
#include<string>
using namespace std;
class ChairMan{
    string name;
    ChairMan(string name){ChairMan::name = name;}

public:
    static ChairMan& getInstanct(){
        static ChairMan cm("***");
        return cm;
    }

    void show(){
        cout << "同志们好!我是主席:" << name <<endl;
    }
};

int main()
{
    //ChairMan C1("XXX");  错误    1    error C2248: “ChairMan::ChairMan”: 无法访问 private 成员(在“ChairMan”类中声明)
    ChairMan::getInstanct().show();
    system("pause");
    return 0;
}

    初始化列表

      在构造函数定义里紧跟参数表之后可以有一个初始化列表,用冒号开头,后面有若干对“成员变量(初始值)“,多对之间用逗号分隔。初始化列表是初始化常量成员和引用成员的不二法门

#include<iostream>
#include<string>
using namespace std;
class ChairMan{
    string name;
    string age;
public:
    ChairMan(string n,string a):name(n),age(a){}
    void show(){
        cout << "同志们好!我是主席:" << name <<endl;
        cout << "今年" << age << "" <<endl;
    }
};

int main()
{
    ChairMan C1("XXX","55"); 
    C1.show();
    system("pause");
    return 0;
}

    动态创建和释放对象

      new 类名              delete 地址

      new 类名(参数)          delete 地址

      new 类名[个数]          delete[] 地址

      返回的都是地址 free(p)/delete p/p=NULL;

    一个变量的创建和释放

      全局变量: main执行之前创建,main返回后释放

      静态局部变量: 第一次执行到时创建,main返回后释放

      普通局部变量:(含形参)每次执行到的时候创建,超出作用范围时释放

      临时结果:临时创建,当场使用,立即释放

      动态变量:执行new的时候创建,执行delete时候释放

    析构函数

    析构函数是一个特殊的由用户定义的成员函数,当该类的对象离开了它的域或者delete表达式应用到一个该类的对象的指针上时,析构函数会自动被调用,名字为类名前加~,他不返回任何值也没有任何参数,所以不能重载,尽管我们可以为一个类定义多个构造函数,但是我们只能提供一个析构函数,它将被应用在类的所有对象上

    默认析构函数:如果一个类没有定义析构函数,编译器会自动生成一个什么也不做的析构函数。

    

    

#include<iostream>
using namespace std;
#include <string>

class File{
    string path;
public:
    File(const string& path="无名"):path(path)//冒号后第一个path是成员,第二个是形参 //构造函数 
    {
        cout<<"创建文件"<<path<<endl;
    } 
    ~File() //析构函数
    {
        cout<<"释放对象"<<path<<endl;
    }
};

int main()
{
    File* p1 = new File;
    File* p2 = new File("D:\My Documents\Visual Studio 2010");
    File* p3 = new File[3];

    delete[] p3;p3=NULL;
    delete p1;p1=NULL;
    delete p2;p2=NULL;
    system("pause");
    return 0;
}

  

  

 

posted @ 2016-04-30 23:15  Visions  阅读(176)  评论(0)    收藏  举报