天天看點

c++類和對象,構造函數,函數重載,複合類。

c++類和對象,構造函數,函數重載,複合類。

1.

面向過程和面向對象主要差別可以簡單概括為:面向過程的程式設計是一種直接的程式設計方法是按照編

程語言的思路考慮問題;面向對象的程式設計是一種抽象度更高的程式設計方法,它的目标是使

子產品的抽象度更高,可複用性更好。

2.

面向對象的三大特征:封裝性、繼承性和多态性。

3.

封裝:隐藏對象的屬性和實作細節,僅對外提供公共通路方式。

繼承:子類繼承父類的屬性和方法,實作代碼的複用。

多态:C++多态性是通過虛函數來實作的,虛函數允許子類重新定義成員函數,而子類重新定義父類的做法稱為覆寫(override),或者稱為重寫。(這裡我覺得要補充,重寫的話可以有兩種,直接重寫成員函數和重寫虛函數,隻有重寫了虛函數的才能算作是展現了C++多态性)而重載則是允許有多個同名的函數,而這些函數的參數清單不同,允許參數個數不同,參數類型不同,或者兩者都不同。編譯器會根據這些函數的不同清單,将同名的函數的名稱做修飾,進而生成一些不同名稱的預處理函數,來實作同名函數調用時的重載問題。但這并沒有展現多态性。

4.

類和對象的關系:類是對象的抽象類型,而對象是類的具體執行個體。

5.

結構體和類的差別:結構體成員預設是public,類成員預設是private.

6.

//定義一個圓類。屬性:圓心坐标以及半徑,操作:對圓的資訊進行讀取、設

//置以及列印,計算兩個圓之間的距離。

#include <iostream>

#include <math.h>

using namespace std;

class Cicle

{

    float x;

    float y;

    float r;

public:

    void set(float a,float b,float c)

    {

        x=a;

        y=b;

        r=c;

    }

    float getx()

    {

        return x;

    }

    float gety()

    {

       return y;

    }

    float getr()

    {

        return r;

    }

    void print()

    {

        cout <<"(" << x <<"," << y << ")" << endl;

    }

    float d(Cicle s)

    {

        return sqrt((x-s.x)*(x-s.x)+(s.y-y)*(s.y-y));

    }

};

int main(int argc, const char * argv[]) {

    Cicle a,b;

    a.set(1.0, 1.0, 1.0);

    b.set(2.0, 2.0, 2.0);

    cout << a.getx() <<endl;

    cout << a.gety() <<endl;

    cout << a.getr() <<endl;

    cout << b.getx() <<endl;

    cout << b.gety() <<endl;

    cout << b.getr() <<endl;

    cout <<a.d(b) <<endl;

    a.print();

    b.print();

    return 0;

}

7。

三、構造函數

3.1 構造函數特點

  構造函數是一種比較特殊的成員函數,用于建立并初始化對象。聲明對象時構造函

數會被編譯器自動調用。

構造函數的四個特點:

(1)構造函數的通路權限必須為公有(public); (2)構造函數名和類名相同; (3)構造函數沒有傳回值; (4)構造函數可以帶參數,用于初始化成員變量;

3.2 預設構造函數

預設構造函數分兩種: 1、構造函數不帶參數;2、構造函數帶參數但參數都有預設 值。

   Example codes:

Circle(); // Circle(float a=0,float b=0,float c=0);// Circle(float a,float b,float c); //

  預設構造函數是指在聲明對象時,可以不傳遞參數,使用空值或預設值對對象進行

初始化,而普通構造函數在聲明對象時必須傳遞參數(實參),否則構造函數的參數(形 參)沒有值,編譯出錯。

  如果程式員一個構造函數都沒寫,編譯器将提供一個空的預設構造函數,它不會對

資料成員進行初始化。一旦程式員提供了構造函數,編譯器将不提供預設構造函數。對

于每個類都寫一個預設構造函數,是程式員的一個好習慣。



#include <iostream>

using namespace std;

class Thing

{

public:

Thing( int a=10, int b=20, int c = 30)//

{ x=a; y=b; z=c; }//,,

    void printThing() {

        cout<<"x="<<x<<" y="<<y<<" z="<<z<<endl;

} private:

    int x;

    int y;

    int z;

};

int main(int argc, const char * argv[]) {

    Thing t;

    t.printThing();

Thing s(1);// s.printThing();

    Thing r(1,2);

    r.printThing();

    Thing v(1,2,3);

    v.printThing();

    return 0;

}

示例分析: 聲明t對象時,沒有傳遞參數,那麼編譯器将會調用預設構造函數,而類中剛好提供

了一個預設構造函數。 假如将Thing( int a=10, int b=20, int c = 30)的三個預設 值都去掉Thing( int a, int b, int c),再次編譯程式會發現,聲明t對象、s對象、r

No matching constructor for initialization of ‘Thing’ 而v對象不會出錯。

8.

函數重載

1.1 函數重載的概念

什麼是函數重載?在同一個作用域中,可以有一組具有相同函數名,不同參數清單 的函數,這組函數被稱為重載函數。參數清單不同是指參數的個數或參數的類型不同。 如:

    void f();

    void f(int x);

    void f(int x,float y);

  如果僅僅是函數的傳回值類型不同,不能是函數的重載:

     void f(int x);

     int  f(int x);  //error: Functions that differ only in their return

                     //       type cannot be overloaded.

  這兩個函數不是函數的重載,在同一個作用域内是不能共存的,因為在函數調用時

不知道該調用哪一個函數。

例1-1】構造函數重載

#include <iostream>

using namespace std;

class Thing

{

public:

    Thing( ) {x =0; y= 0; z=0;}  //default constructor

    Thing(int a) { x=a;}

    Thing(int a, int b) {x=a;y=b;}

    Thing(int a, int b, int c) { x=a; y=b; z=c; }

    void printThing() {

        cout<<“x=“<<x<<",y="<<y<<",z="<<z<<endl;

}

private:

    int x;

int y;

int z; };

int main(int argc, const char * argv[]) {

    Thing t;

    t.printThing();

    Thing s(1);

    s.printThing();

    Thing r(1,2);

    r.printThing();

    Thing v(1,2,3);

    v.printThing();

    return 0;

}

示例分析: (1)類中可以定義多個構造函數,但是必須能夠構成函數重載;

(2)聲明對象時的參數類型和個數要與構造函數的參數進行比對。 16年7月22日 星期五

二、初始化清單

在使用C++程式設計的過程當中,常常需要在構造函數中對類的成員變量進行初始化,通 常的方法有兩種:

  第一種方法:在構造函數體内通過指派語句初始化

       Thing(int a,int b,int c){ x = a; y = b; z = c; }

  第二種方法:使用初始化清單形式初始化

       Thing(int a,int b,int c):x(a), y(b), z(c) { }

程式中為什麼要使用初始化清單? (1)對于類類型的成員,使用初始化清單效率更高。

(2)有些類型的成員變量必須使用初始化清單的形式初始化,如const成員、引用 成員。

(3)在繼承時,子類的構造函數中初始化父類的成員時。

例2-1】初始化清單的使用

// Created by Mr_lee on 16/7/22.

// Copyright © 2016 . All rights reserved.

#include <iostream>

using namespace std;

class Thing

{

public:

    Thing(int _x,int _y) : x(_x), y(_y){ }

    void print() {

        cout<<"x="<<x<<",y="<<y<<endl;

    }

private:

    int x;

int y; };

int main(int argc, const char * argv[]) {

    Thing t(1,1);

t.print();

return 0; }

三、複合類

複合類也稱為組合類,是指将一個類的對象作為另一個類的成員變量。 例3-1】複合類示例

#include <iostream>

using namespace std;

class Point

{

public:

    Point();

    Point(float _x,float _y);

    void print();

private:

    float x;

float y; };

Point::Point(){ }

Point::Point(float _x,float _y) {

    x = _x;

y = _y; }

void Point::print() {

    cout<<"("<<x<<","<<y<<")"<<endl;

}

//—————————————— ———————————————// class Circle

{ public:

    Circle();

    Circle(float x,float y,float r);

    void setCircle(float r,Point p);

    void print();

private:

    float radius;

    Point center;

};



Circle::Circle(){} //center

//Point Circle::Circle(float x,float y,float r):center(x,y),radius(r) { }

void Circle::setCircle(float r,Point p) {

    radius = r;

center = p; }

void Circle::print() {

    cout<<"radius:"<<radius<<endl;

    center.print();

}

int main(int argc, const char * argv[]) {

    Point p(5,7);

    p.print();

    Circle c;

    c.setCircle(1, p);

    c.print();

    return 0;

}

繼續閱讀