C到C++的過渡
/*
*運行平臺:Visual Studio 2015(Debug x86)
*參考資料:《C++ Primer Plus(第6版)》,傳智掃地增C++基礎課程
*/
目錄
一、面向對象的思想
1、什麼是面向對象的思想
這個對象有下面的兩種說法:
- 一般意義上的對象:是現實世界中一個實際存在的事物,可以是有形的(比如一輛汽車),也可以是無形的(比如一項計劃),是構成世界的一個獨立單位,具有靜態特徵(可以用某種數據來描述)和動態特徵(對象所表現的行爲或具有的功能)
- 面向對象方法中的對象:
是系統中用來描述客觀事物的一個實體,它是用來構成系統的一個基本單位。對象由一組屬性和一組行爲構成。
屬性:用來描述對象靜態特徵的數據項。
行爲:用來描述對象動態特徵的操作序列。
具體可以看看這篇文章
下面用一道編程題目來簡單說明一下:
題目:在C++環境下,編寫程序使其輸入一個半徑值,求這個半徑對應的圓的面積?
2、採用結構化思想編程
程序如下:
#include "iostream"
using namespace std; //使用命名空間 std 標準的命名空間 (在這個命名空間中定義了很多標準定義)
int main()
{
double r;
double area;
cout << "請輸入r:";
cin >> r;
area = 3.1415*r*r;
cout << "結果爲:" << area << endl;
system("pause");
return 0;
}
這個程序裏面,採用自頂向下結構,很清晰。
3、採用面向對象的思想編程
#include "iostream"
using namespace std;
/* 面向對象 */
class circle
{
public:
double g_r;
double pi = 3.1415;
double area;
public:
double getS() //求面積函數
{
area = pi*g_r*g_r;
return area;
}
};
int main()
{
circle r1; //新建一個類型爲circle對象名爲r1的對象
cout << "請輸入r:";
cin >> r1.g_r;
cout << "結果爲:" << r1.getS()<< endl;
system("pause");
r
通過以上兩個程序的對比,所謂的面向的是對象,什麼意思呢?
如上的題目中的參數,圓的半徑和圓的面積,他們都屬於圓的固有屬性,具有1對多的特徵,即一個圓,擁有半徑、直徑、周長、面積等等的屬性,那麼這個圓就可以被稱作爲一類事物class circle
,這個圓的名字r1
就叫做對象。
二、C++對C的加強
1、namespace命名空間
概念:namespace,是指標識符的各種可見範圍。C++標準程序庫中的所有標識符都被定義於一個名爲std的namespace中。
- 在C中的空間中:
C語言中只有一個全局作用域,所有的全局標識符共享同一個作用域,標識符之間可能發生衝突 。
- 在C++中的命名空間中:
爲了解決以上衝突問題,C++中提出了命名空間的概念。將命名空間將全局作用域分成不同的部分,不同命名空間中的標識符可以同名而不會發生衝突,命名空間也可以相互嵌套。
1.1 自定義命名空間
使用方式:namespace+自定義命名空間名字{}
#include "iostream"
using namespace std;
/* 自定義命名空間 */
namespace NamespaceA
{
char a = 'A';
}
namespace NamespaceB
{
char a = 'B';
}
如何使用這個命名空間呢?
使用方式:using namespace+自定義命名空間名字
int main()
{
using namespace NamespaceA;
using namespace NamespaceB;
cout << NamespaceA::a << endl;
cout << NamespaceB::a << endl;
system("pause");
return 0;
}
1.2 命名空間相互嵌套
namespace NamespaceB
{
char a = 'B';
namespace NamespaceC
{
struct Teacher
{
char name[10] = "CC";
int age = 0 ;
};
}
}
如何使用這個命名空間呢?
使用方式(針對結構體):using 自定義命名空間名字::嵌套命名空間名字::結構體類型;
int main()
{
using NamespaceB::NamespaceC::Teacher;
Teacher t1;
//方法二:unsing NamespaceB::NamespaceC::Teacher t1;
cout << t1.name << endl;
system("pause");
return 0;
}
2、“實用性”增加
- 在C中必須要在作用域開始的位置定義變量
int main()
{
{ /* 正確 */
int i = 0;
int j = 1;
printf("%d",i);
printf("%d",j);
}
{ /* 錯誤 */
int i = 0;
printf("%d",i);
int j = 1;
printf("%d",j);
}
}
- 在C++中強調實用性,可以在需要使用時再定義
int main()
{
{ /* 正確 */
int i = 0;
printf("%d",i);
int j = 1;
printf("%d",j);
}
}
3、struct類型加強
- C語言的struct定義了一組變量的集合,C編譯器並不認爲這是一種新的類型
struct Teacher
{
char name[10];
int age;
};
當在main
函數中這樣定義時Teacher t1;
會報錯。正確:struct Teacher t1;
- C++中的struct是一個新類型的定義聲明
struct Teacher
{
char name[10];
int age;
};
在main
函數允許這樣定義:Teacher t1;
4、新增Bool類型關鍵字
bool名爲布爾類型,可取的值只有true和false,理論上bool只佔用一個字節。
- true代表真值,編譯器內部用1來表示
- false代表非真值,編譯器內部用0來表示
提問:那bool可以賦值嗎?
回答:執行bool=2
,編譯可以通過,但是bool輸出值爲1不爲2。
執行bool=-2
,編譯可以通過,但是bool輸出值爲1不爲-2。
執行bool=0
,編譯可以通過,但是bool輸出值爲0。
總結:bool賦值時將非0值轉換爲true,0值轉換爲false。
5、三目運算符的增強
- C語言中三目運算符返回的是:變量的值
如何證明?
證明:在C編譯器中執行下列語句
int main()
{
int a = 10;
int b = 20;
(a>b? a:b) = 30
}
結果:會發現編譯器報錯。
原因:三目運算符返回的是變量的值,即執行(a>b? a:b)
得到的是b的值,20
。
- C++中三目運算符返回的是:變量本身
如何證明?
證明:在C++編譯器中執行下列語句
int main()
{
int a = 10;
int b = 20;
(a>b? a:b) = 30
}
結果:會發現編譯器成功。
原因:三目運算符返回的是變量本身,即執行(a>b? a:b)
得到的是變量b
,之後變量b賦值爲30
。
提問:那麼C++編譯器是如何實現的呢?
回答:1、從C的角度去分析,相當於(a>b? &a:&b)
。
2、從C++的角度分析,相當於C++編譯器手工去執行(a>b? &a:&b)
。
注意:上面所說的是從變量的角度,如果是(a>b? 1:2) = 30
,那麼無論是C還是C++編譯器,他們都會報錯。
當然,對於C++對C的優化與升級遠遠不止上述介紹的那麼少,通過後續的學習將逐漸完善。