面向对象(一)

面向对象的基本特征:
1、抽象:从具体到一半的过程。抓住事物的本质,而不是内部的具体实现细节。

2、封装:把对象的属性和操作结合在一起,构成一个独立的对象;对外提供一定的接口,在对象之外只能通过接口对对象进行操作;封装增加了对象的独立性,从而保证了数据的可靠性;

3、继承:表达了对象的一般与特殊的关系。特殊类的对象具有一般类的全部属性和服务。当定义一个类后,又需要定义一个新
类,这个新类与原来的类相比,只是增加或修改了部分属性和操作,这时可以用原来的类派生出新类,新类中只需要描述自己所特有的属性和操作。继承简化了对问题的描述,大大提高了程序的可重用性。

4、多态:同一个消息被不同的对象接收时,产生不同的结果,即实现同一个接口,不同方法。一般类中定义的属性和服务,在特
殊类中不改变其名字,但通过各自不同的实现后,可以具有不同的数据类型或不同的行为。

继承和多态性组合,可以生成很多相似但又独一无二的对象。继承性使得这些对象可以共享许多相似特性,而多态又使同一个操作对不同对象产生不同表现形式。这样不仅提高了程序设计的灵活性,而且减轻了分别设计的负担。

内联函数:
内联函数能够提高运行效率,将代码直接嵌入到调入的地方,从而减少了函数调用的开销。程序的体积会增大,以空间换时间。
两种方法实现内联:1、在类中声明,在实现的时候加上inline关键字; 2、在类中直接实现,即使没有加上inline关键字

函数可进行重载,要求相同的作用域。成员函数可以进行重载,要求在类作用域当中。

c++中结构体可以有成员函数。
class与struct的区别:struct默认的是私有成员,struct默认是共有成员。

类的作用域:
1、每个类都定义了自己的作用域称为类作用域;
2、类作用域中说明的标识符只在类中可见。

类作用域:作用域在在类内部
块作用域:作用域在花括号内的,不会影响块作用域外部的变量
文件作用域:在任何代码之外的作用域,在定义的地方到文件结尾有效
函数原型作用域:int Add(int a ,int b) a,b作用域为函数原型作用域,所以在函数定义和函数声明的地方可以同名
函数作用域:在函数内部,主要用于goto语句

前向声明:
1、c++中类必须先定义,才能够实例化。
2、两个类需要相互引用形成一个“环形”引用时,无法先定义适用。这时候需要前向引用。
3、前向声明的类不能实例化

类的嵌套,嵌套类被隐藏在外围类中,该类名只能在外围类中使用。

//类的嵌套
class Outer
{
    class Inner
    {
    public:
        void fun()
        {
            cout << "Inner::fun..." << endl;
        }
    };
public:
    Inner obj_;
    void Fun()
    {
        cout << "Outer::fun.." << endl;
        obj_.fun();
    }
};

int main()
{
    Outer o_;
    o_.Fun();
    system("Pause");
    return 0;
}

如果在外围类的作用域使用该类名时,需要加类的作用域运算符。嵌套类的成员函数可以定义在外围类之外定义。

class Outer
{
    class Inner
    {
    public:
        void fun();
    };
public:
    Inner obj_;
    void Fun()
    {
        cout << "Outer::fun.." << endl;
        obj_.fun();
    }
};

void Outer::Inner::fun()
{
    cout << "Inner::fun.." << endl;
}
int main()
{
    Outer o_;
    o_.Fun();
    system("Pause");
    return 0;
}

嵌套类的成员函数对外围类的成员没有访问权,反之亦然。

类也可以定义在函数体内,这样的类被称为局部类。局部类只在定义它的局部域内可见。
局部类的成员函数必须被定义在函数类体内。
局部类中不能有静态成员。

void fun()
{
    class LocalClass
    {
    public:
        void Init(int num)
        {
            num_ = num;
        }
        void Display()
        {
            cout << "num_=" << num_ << endl;
        }
    private:
        int num_;
        //static int num2_;  // 局部类中不能定义静态成员
    };
    LocalClass LC_;  
    LC_.Init(5);
    LC_.Display();
}

构造函数:
构造函数是特殊的成员函数;
创建类的新对象,系统自动会调用析构函数;
构造函数是为了保证对象的每个数据成员都被正确初始化;

1、函数名与类名完全相同
2、不能定义构造函数的类型(返回类型),也不能使用void
3、通常构造函数被声明为共有的,否则不能被显式的调用。私有构造函数也有其用途。
4、构造函数可以有任意类型和任意个数的参数,一个类可以有多个构造函数(重载)

当没有声明构造函数,类中会自动生成不带参数的构造函数。当声明带参数的构造函数时,类就不会自动生成不带参数的构造函数,此时,可以显式的声明构造函数。

全局对象的构造先于main函数

Test t(10);  //全局对象的构造先与main函数
int main()
{
    cout << "main start.." << endl;
}
image.png

在栈区创建的对象,在生存周期结束时会自动调用析构函数,在堆上创建的对象,要由程序员显式调用delete来释放,同时调用析构函数。

//全局对象的构造先与main函数
int main()
{
    Test t[2] = { 10,20 };
    Test *p1 = new Test(2);
    delete p1;  //delete显式调用该释放对象,同时调用析构函数
    Test *p2 = new Test[2];
    delete[] p2;
    cout << "main start.." << endl;
}
image.png

构造函数作用:
初始化;
转换构造函数;

int main()
{
    Test t1(10);  //带一个参数的构造函数,充当的是普通构造函数的功能
    t1 = 30;   //将20这个整数赋值给t1对象
                //1、调用转换构造函数将20这个整数转换成类类型,生成一个临时对象
                //2、将临时对象赋值给t对象

    Test t2 = 20; //等价于Test t2(20); 这里的不是运算符,表示初始化
    
    cout << "main start.." << endl;
    return 0;
}
image.png
class Test
{
public:
    void Display();
    Test& operator=(const Test& other);
    Test();
    Test(int num);
    ~Test();
private:
    int num_;
};



Test& Test::operator=(const Test& other)
{
    num_ = other.num_;
    cout << "Test::operator=" << endl;
    return *this;
}


int main()
{
    Test t1(10);  //带一个参数的构造函数,充当的是普通构造函数的功能
    t1 = 30;   //将20这个整数赋值给t1对象  
                //1、调用转换构造函数将20这个整数转换成类类型,生成一个临时对象,此时的=已经被重载
                //2、将临时对象赋值给t对象,再销毁新建的临时变量

    Test t2 = 20; //等价于Test t2(20); 这里的不是运算符,表示初始化
    
    cout << "main start.." << endl;
    return 0;
}
image.png

explicit,只提供给类的构造函数使用的关键字
编译器不会把声明为explcit的构造函数用于隐式转换,它只能在程序diamante中显式创建对象

在构造函数初始化列表进行数据成员初始化

Clock::Clock(int hour , int minute ,int second :hour_(hour),minute_(minute),second_(second))

构造函数的执行分为两个阶段:
1、初始化段
2、普通计算段

class Object
{
public:
    Object(int num) :num_(num) //数据成员初始化
    {
        cout << "Object..." << endl;
    }
    ~Object()
    {
        cout << "~Object..." << endl;
    }
private:
    int num_;
};

class Container
{
public:
    Container(int obj1 = 0, int obj2 = 0) :obj1_(obj1), obj2_(obj2)  //初始化列表中进行初始化
    {
        cout << "Container..." << endl;
    }
    ~Container()
    {
        cout << "~Container..." << endl;
    }
private:
    Object obj1_; //没有默认的构造函数,需要在之前对构造函数进行初始化赋值
    Object obj2_;//缺省传参,使用默认值
};

const数据成员只能在构造函数初始化列表中进行初始化
引用成员也只能在构造函数初始化列表中进行初始化
对象成员(对象所对应的类没有默认构造函数)的初始化,也只能在构造函数初始化列表中进行

class Object
{
public:
    Object(int num) :num_(num),knum_(30),refnum_(num_) //对象成员初始化
    {
        cout << "Object..." << endl;
    }
    ~Object()
    {
        cout << "~Object..." << endl;
    }
private:
    int num_;
    const int knum_;
    int &refnum_;
};


const只能对每个对象来说是常量,不适用所有对象,枚举则使用于所有对象

class Object
{
public:
    enum E_TYPE
    {
        TYPE_A = 100,  //枚举只有逗号分隔
        TYPE_B = 200
    };

public:
    Object(int num) :num_(num),knum_(30),refnum_(num_) //对象成员初始化
    {
        cout << "Object..." << endl;
    }
    ~Object()
    {
        cout << "~Object..." << endl;
    }
    void Displayknum()
    {
        cout << "knum_=" << knum_ << endl;
    }
private:
    int num_;
    const int knum_;
    int &refnum_;
};
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容

  • C++ 面向对象 c++创建对象的时候如果使用new运算符,将会返回返回一个指针,指向堆中的内存地址 类,对象类定...
    小小小8021阅读 285评论 0 0
  • 这是16年5月份编辑的一份比较杂乱适合自己观看的学习记录文档,今天18年5月份再次想写文章,发现简书还为我保存起的...
    Jenaral阅读 2,729评论 2 9
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy阅读 9,504评论 1 51
  • C++类和对象 C++ 在 C 语言的基础上增加了面向对象编程,C++ 支持面向对象程序设计。类是 C++ 的核心...
    863cda997e42阅读 633评论 0 4
  • 能在巴学园工作和学习该是多么幸福呀!能有一个这样平易近人的校长该是多么难忘呀!看完《窗边的小豆豆》,那阵阵笑声...
    二爷阅读 634评论 0 0