天天看點

01.C++(一)----面向對象的思想

(建立于2017/12/20)

1.命名空間

namespace :C++引入的用于解決多個子產品間命名沖突問題的一個機制,他是一個由程式設計者命名的記憶體區域,程式設計者可以根據需要指定一些有名字的空間域,把一些全局實體分别放在各個命名空間中,進而與其他全局實體分隔開來。

#include <stdlib.h>
#include<iostream>
//标準命名空間(包含很多标準的定義)
//命名空間類似于Java中的包
using namespace std;

//自定義命名空間
namespace NSP_A {
    int a = 9;
    struct Teacher
    {
        char name[29];
        int age;
    };

    struct Student
    {
        char name[29];
        int age;
    };
}

namespace NSP_B {
    int a = 12;

    //命名空間嵌套
    namespace NSP_C {
        int c = 90;
     }

    struct Teacher
    {
        char name[29];
        int age;
    };

    struct Student
    {
        char name[29];
        int age;
    };
}

void main() {
    //<<運算符重載
    //std::cout << "this is a c ++" << std::endl;
    //上邊一行可以寫成下邊的樣子,不過需要添加 using namespace std;
    cout << "this is a c++" << endl;

    //使用命名空間
    //::通路修飾符
    cout << NSP_A::a << endl;
    cout << NSP_B::a << endl;
    //通路命名空間中的命名空間的值
    cout << NSP_B::NSP_C::c << endl;

    //通路命名空間中的結構體(struct寫與不寫都可以)
    //struct  NSP_A::Teacher t;
    //t.age = 123;
    //struct NSP_A::Student s;
    //s.age = 12;

    //上邊四行可以寫作這種形式
    using namespace NSP_A;
    Teacher t;
    t.age = 123;
    Student s;
    s.age = 12;

    cout << t.age << endl;
    cout << s.age << endl;

    //如果多個命名空間中有相同的比如說結構體,我們需要每個都通路到(似乎會包重複的問題)
    //嚴重性   代碼  說明  項目  檔案  行   禁止顯示狀态
    //錯誤    C2086   “NSP_A::Student s” : 重定義    C++_study   c : \users\renzhenming\documents\visual studio 2015\projects\c++_study\c++_study\1.cpp  75


    //Student s;
    //s.age = 300;
    //cout << s.age << endl;
    
    using NSP_B::Student;
    Student s1;
    s1.age = 200;   
    cout << s1.age << endl;

    system("pause");
}

輸出結果:

this is a c++
9
12
90
123
12
200
請按任意鍵繼續. . .

           

(2018年7月29日補充)

2.第一個c++程式
#include "iostream"  //包含c++的頭檔案

//使用std标準命名空間,在這個空間中定義了很多标準定義
using namespace std;

void main() {

    //輸出到螢幕
    cout << "hello world" << endl;
    system("pause");
}

           
2.以面向過程的方式求圓的面積
#include "iostream"  //包含c++的頭檔案

//使用std标準命名空間,在這個空間中定義了很多标準定義
using namespace std;

void main() {

    double r = 0;
    double s = 0;

    cout << "請輸入圓的半徑" << endl;

    //cin标準輸入,表示鍵盤
    cin >> r;
    cout <<"半徑的值是:"<<r << endl;
    s = 3.14*r*r;
    //輸出到螢幕
    cout << "圓的面積是s:"<<s << endl;
    system("pause");
}

           
3.以面向對象的方式求圓的面積

C++雖然是基于c語言,但是二者有本質不同,C++是面向對象程式設計,C語言是面向過程程式設計,學習c++要首先進行思想的轉變,對于由Java基礎的同學來說,這一點了解起來會比較容易,既然以面向對象的方式解決這個需求,那麼很明顯,圓就是我們要處理的這個對象

#include "iostream"  //包含c++的頭檔案

//使用std标準命名空間,在這個空間中定義了很多标準定義
using namespace std;

//在c++中定義了一個自定義資料類型Circle
class Circle
{
//成員變量 public類型的
public:
    double m_s;   //面積
    double m_r;   //半徑
//成員函數,public類型
public:
    void setR(double r) {
        m_r = r;
    }
    double getR() {
        return m_r;
    }
    double getS() {
        m_s = 3.14*m_r*m_r;
        return m_s;
    }
};

void main() {
        //用類定義三個對象
    Circle c1, c2, c3;
    double r;
    cout << "請輸入半徑:"<< endl;
    cin >> r;
    c1.setR(r);
    cout << "圓的面積是s:"<<c1.getS()<< endl;
    system("pause");
}

           

類是一個資料類型(固定大小記憶體塊的别名),定義一個類,是一個抽象的概念,此時不會配置設定記憶體,隻有在用資料類型定義變量的時候才會配置設定記憶體。上邊的代碼中使用一個資料類型定義了三個變量c1 c2 c3,那麼在c1調用類方法的時候,編譯器是如何區分c1 c2 c3的呢?

3.C++對C的擴充

a.namespace命名空間

b.實用性加強

在早期C語言編譯器中,變量必須在使用域開始的地方定義,否則編譯無法通過,如下這種方式是錯誤的,因為在列印語句之後又定義了一個變量b,正确的寫法是先定義在列印。不過c++改變了這種情況,在c++中隻要在使用前定義即可,位置沒有要求

#include <stdio.h>
int main() {
    int a=1;
    printf("%d\n", a);
    int b = 2;
    printf("%d\n", b);
    system("pause");
    return 0;
}
           

c.變量檢測

C語言中,重複定義的同名全局變量是合法的,多個全局變量會被連結到全局資料區的同一個位址空間

int a;
int a = 1;
           

在c++中,拒絕這種二次定義的形式,編譯無法通過

d.struct類型加強

1.c語言的struct定義了一組變量的集合,c編譯器并不認為這是一種新的類型,c++的struct是一個新類型的定義聲明。什麼意思?看下邊這種使用結構體的方式在C語言編譯器是無法編譯通過的,定義結構體變量要前邊加struct關鍵字。但是在c++編譯器是可以的

2.另外,c++中,結構體内的變量也可以使用權限修飾符public protected等

3.c++中的結構體可以和class完成相同的功能

#include <stdio.h>
struct Me {
    int a;
};
int main() {
    Me me1;  //struct Me me1;
    me1.a = 10;
    printf("%d\n", me1.a);
    system("pause");
    return 0;
}
           
#include "iostream"  //包含c++的頭檔案
//使用std标準命名空間,在這個空間中定義了很多标準定義
using namespace std;
#include <stdio.h>
struct Me {
public:
    int a;
protected:
    int b;
};
int main() {
    Me me1; 
    me1.a = 10;
    printf("%d\n", me1.a);
    system("pause");
    return 0;
}
           

e.register關鍵字增強

register關鍵字請求編譯器将局部變量存儲在寄存器中,使用register修飾變量,暗示編譯程式相應的變量将被頻繁的使用,應盡可能(不是絕對的,是在寄存器空閑的狀态下有效)的将它儲存在寄存器中,以加快存儲速度。在C語言中register關鍵字定義的變量無法取位址,并且隻有手動加上register關鍵字的變量才會有可能被優化。c++中也支援register關鍵字,不過c++有自己的優化方式,不使用register關鍵字也可以根據情況自動判斷是否需要對代碼進行優化,c++可以取得register變量的位址。

f.c++中所有變量和函數都必須有類型

C語言中預設類型在c++中是不合法的

g.新增bool類型

bool可取值隻有true false,理論上隻占一個位元組,true代表真值,編譯器内部用1表示,false表示非真,編譯器内部用0表示

h.C++和C語言的三目運算符

C語言傳回變量的值,C++傳回變量的本身

C語言中的三目運算符傳回的是變量值,不能做左值使用,C++中的三目運算符可直接傳回變量本身,是以可以出現在程式任何地方

如下是在C語言中,編譯器直接提示表達式必須是可修改的左值,因為C語言三目運算符傳回的是變量的值,那麼因為a小于b,是以傳回a的值,a的值是10,然後将30指派給10,這是錯誤的。常量無法被修改

#include <stdio.h>
int main() {
    int a = 10;
    int b = 20;
    (a < b ? a : b) = 30;
    system("pause");
    return 0;
}
           

在C++中會怎樣呢?

#include "iostream"  //包含c++的頭檔案
using namespace std;
int main() {
    int a = 10;
    int b = 20;
    (a < b ? a : b) = 30;
    cout << a<< endl;
    system("pause");
    return 0;
}
           

可以發現編譯通過并且列印a的值為30,因為C++三目運算符傳回的是變量本身,相當于多了一步取位址的操作,然後直接操作a指向的記憶體空間

C語言如何實作這種效果?隻需要稍作改動,其實c++中編譯器相當于幫我們做了這一步

#include <stdio.h>

int main() {
    int a = 10;
    int b = 20;
    *(a < b ? &a : &b) = 30;
    printf("a=%d\n", a);
    system("pause");
    return 0;
}
           

i.C和C++中的const

const的作用是為了防止變量被修改,但實際上在C語言中,const是有缺陷的

C語言代碼,可以發現通過指針修改了const變量a

#include <stdio.h>

int main() {
    const int a = 10;
    int *p = &a;
    printf("*p=%d\n", *p);
    printf("a=%d\n", a);
    system("pause");
    return 0;
}
           

在c++中,這段代碼無法編譯通過,測試使用的編譯器是Visual Studio2015,可能在早期的版本上編譯可以通過,但是運作無法修改const常量值。c++編譯器是怎麼做到的?相對于C語言,c++編譯器會将const變量存入符号表中,當你要使用這個變量的時候在符号表中取出,而當你通過取位址的方式指派給一個指針的時候,編譯器會在記憶體中拷貝一份這個變量,是以你同過指針修改的變量跟符号表中的這個變量并沒有關系,進而保證const變量不被修改

//嚴重性   代碼  說明  項目  檔案  行   禁止顯示狀态
//錯誤    C2440   “初始化”: 無法從“const int *”轉換為“int *”   Project8    c:\users\renzhenming
//documents\visual studio 2015\projects\project8\project8\a.cpp 5   
//錯誤(活動)        "const int *" 類型的值不能用于初始化 "int *" 類型的實體 Project8    //c:\Users\renzhenming\Documents\Visual Studio 2015\Projects\Project8\Project8\a.cpp    
//5 

#include "iostream"  //包含c++的頭檔案
using namespace std;
int main() {
    const int a = 10;
    int *p = &a;
    cout << "*p=%d\n"<<*p << endl;
    cout << "a=%d\n"<<a << endl;
    system("pause");
    return 0;
}
           

const變量差別

C語言中const變量

是隻讀變量,有自己的存儲空間

c++中的const常量

可能配置設定空間,也可能不配置設定

當const常量為全局,并且需要在其他檔案中使用,會配置設定空間

當使用&操作符,取const常量位址時,會配置設定空間

當const int &a = 10; const修飾引用時,也會配置設定空間