Java開發者使用C++寫程序踩的坑

筆者是一個很矛盾的人。平時用Java。可是一開始學習的時候學的是彙編語言,並且對C語言也很熟悉。爲何不學C++呢?是由於我能夠徹底用Java的編碼規範去寫C++。所以我不須要了解更多的諸如C++的命名空間,操做符重構,友元函數,多繼承這些更復雜的特性。java

雖然C++介於Java和C之間,我並不須要學C++(開發用Java,腳本用ruby,python,JavaScript)、可是做爲一個計算機從業人員。不瞭解C++有點說不過去。python

首先我先總結此次我學習C++的特性:(參考資料:菜鳥教程)ios

1、using namespace std

第一個讓我疑惑的是using namespace std;ruby

話說回來這個是什麼意思?ide

當我對比了下Java文件的命名規範(類名=文件名.java),我就懂了。函數

使用Java開發的人都明白一個道理、當你import 一個類的時候,Java 的包名.類名的文件定義,並且一切皆對象,會使你不會遇到諸如C++名稱空間的這種錯誤。學習

例如你在頭文件中定義一個函數,這個函數若是被別人又定義了,在編譯時會報錯的。所以C++語言加了個命名空間的語言特性。this

有的同窗可能問了,若是函數名重複了話,能夠重構啊,。。。可是要是參數都同樣呢?編碼

因此C++會用這種方式,定義了一個解決問題的方法。spa

下面是別人總結的。

命名空間(namespace)是一種描述邏輯分組的機制,能夠將按某些標準在邏輯上屬於同一個集團的聲明放在同一個命名空間中。

原來C++標識符的做用域分紅三級:代碼塊({……},如複合語句和函數體)、類和全局。如今,在其中的類和全局之間,標準C++又添加了命名空間這一個做用域級別。

命名空間能夠是全局的,也能夠位於另外一個命名空間之中,可是不能位於類和代碼塊中。因此,在命名空間中聲明的名稱(標識符),默認具備外部連接特性(除非它引用了常量)。

在全部命名空間以外,還存在一個全局命名空間,它對應於文件級的聲明域。所以,在命名空間機制中,原來的全局變量,如今被認爲位於全局命名空間中。

標準C++庫(不包括標準C庫)中所包含的全部內容(包括常量、變量、結構、類和函數等)都被定義在命名空間std(standard標準)中了。

 

std又是什麼呢? std是頭文件<iostream>中的一個命名空間。包含了cin cout endl等函數。

using 指的是用這個命名空間的函數。

具體使用以下:

#include <iostream>
using namespace std;
    
// first name space
namespace first_space{
    void func(){
        cout << "Inside first_space" << endl;
    }
}
    
// second name space
namespace second_space{
    void func(){
        cout << "Inside second_space" << endl;
    }
}
    
int main () {
     
// Calls function from first name space.
first_space::func();
       
// Calls function from second name space.
second_space::func(); 
    
return 0;
} 

 

2、類Class的定義

C++除了支持C語言中的結構體struct外,還支持class。

C語言中的struct裏面不能放方法、可是C++能夠。

不少時候class和struct的差異其實不大。好像在默認訪問權限和繼承方式有所不一樣,其他的我也沒看到什麼新特徵。

不過C++與Java的區別在於C++能夠在定義類以後,在其餘地方定義方法。這個在Java裏面是不行的。Java不能夠這樣。(別跟我說重載)

 

具體的實現以下:

#include <iostream>
 
using namespace std;
 
class Box
{
   public:
      double length;   // 長度
      double breadth;  // 寬度
      double height;   // 高度
};
 
int main( )
{
   Box Box1;        // 聲明 Box1,類型爲 Box
   Box Box2;        // 聲明 Box2,類型爲 Box
   double volume = 0.0;     // 用於存儲體積
 
   // box 1 詳述
   Box1.height = 5.0; 
   Box1.length = 6.0; 
   Box1.breadth = 7.0;
 
   // box 2 詳述
   Box2.height = 10.0;
   Box2.length = 12.0;
   Box2.breadth = 13.0;
 
   // box 1 的體積
   volume = Box1.height * Box1.length * Box1.breadth;
   cout << "Box1 的體積:" << volume <<endl;
 
   // box 2 的體積
   volume = Box2.height * Box2.length * Box2.breadth;
   cout << "Box2 的體積:" << volume <<endl;
   return 0;
}

同時,類的繼承和Java也有區別,他這個竟然直接+:就行了,,,呵呵呵

在派生類(繼承類)中的使用以下

#include <iostream>
 
using namespace std;
 
// 基類
class Shape 
{
   public:
      void setWidth(int w)
      {
         width = w;
      }
      void setHeight(int h)
      {
         height = h;
      }
   protected:
      int width;
      int height;
};
 
// 派生類
class Rectangle: public Shape
{
   public:
      int getArea()
      { 
         return (width * height); 
      }
};
 
int main(void)
{
   Rectangle Rect;
 
   Rect.setWidth(5);
   Rect.setHeight(7);
 
   // 輸出對象的面積
   cout << "Total area: " << Rect.getArea() << endl;
 
   return 0;
}

還有關於多態的問題,和Java差很少。這個我沒有特別細究。應該沒什麼區別吧。。

多態的示例程序以下:

#include <iostream> 
using namespace std;
 
class Shape {
   protected:
      int width, height;
   public:
      Shape( int a=0, int b=0)
      {
         width = a;
         height = b;
      }
      int area()
      {
         cout << "Parent class area :" <<endl;
         return 0;
      }
};
class Rectangle: public Shape{
   public:
      Rectangle( int a=0, int b=0):Shape(a, b) { }
      int area ()
      { 
         cout << "Rectangle class area :" <<endl;
         return (width * height); 
      }
};
class Triangle: public Shape{
   public:
      Triangle( int a=0, int b=0):Shape(a, b) { }
      int area ()
      { 
         cout << "Triangle class area :" <<endl;
         return (width * height / 2); 
      }
};
// 程序的主函數
int main( )
{
   Shape *shape;
   Rectangle rec(10,7);
   Triangle  tri(10,5);
 
   // 存儲矩形的地址
   shape = &rec;
   // 調用矩形的求面積函數 area
   shape->area();
 
   // 存儲三角形的地址
   shape = &tri;
   // 調用三角形的求面積函數 area
   shape->area();
   
   return 0;
}

Java的抽象函數和接口在C++裏面也有體現

對應的叫虛函數。

虛函數 是在基類中使用關鍵字 virtual 聲明的函數。在派生類中從新定義基類中定義的虛函數時,會告訴編譯器不要靜態連接到該函數。

咱們想要的是在程序中任意點能夠根據所調用的對象類型來選擇調用的函數,這種操做被稱爲動態連接,或後期綁定

class Shape {
   protected:
      int width, height;
   public:
      Shape( int a=0, int b=0)
      {
         width = a;
         height = b;
      }
      // pure virtual function
      virtual int area() = 0;
};

而後子類繼承後,就順利的重載。

接口的話,就是完徹底全的那種純虛函數。

像這種的

class Box
{
   public:
      // 純虛函數
      virtual double getVolume() = 0;
   private:
      double length;      // 長度
      double breadth;     // 寬度
      double height;      // 高度
};

3、模板

在Java裏面沒有模板的概念。那個叫泛型。在集合類,容器類等等應用十分普遍。可是C++這裏不知道爲啥又叫模板又叫泛型。。管他呢反正都是一個東西。

定義的以下

template <class type> ret-type func-name(parameter list)
{
   // 函數的主體
}

具體的實現以下

#include <iostream>
#include <string>
 
using namespace std;
 
template <typename T>
inline T const& Max (T const& a, T const& b) 
{ 
    return a < b ? b:a; 
} 
int main ()
{
 
    int i = 39;
    int j = 20;
    cout << "Max(i, j): " << Max(i, j) << endl; 
 
    double f1 = 13.5; 
    double f2 = 20.7; 
    cout << "Max(f1, f2): " << Max(f1, f2) << endl; 
 
    string s1 = "Hello"; 
    string s2 = "World"; 
    cout << "Max(s1, s2): " << Max(s1, s2) << endl; 
 
   return 0;
}

 

這樣就實現了相似於Java中的集合類的方法。

4、操做符的重載

重載這個我是真感受C++太自由了。

也許C++本就不是爲工程而設計的。

而是爲一羣真正的計算機愛好者定製的。

Java除了String 貌似別的都不行。哈哈

重載的運算符是帶有特殊名稱的函數,函數名是由關鍵字 operator 和其後要重載的運算符符號構成的。與其餘函數同樣,重載運算符有一個返回類型和一個參數列表。

像這樣:

#include <iostream>
using namespace std;
 
class Box
{
   public:
 
      double getVolume(void)
      {
         return length * breadth * height;
      }
      void setLength( double len )
      {
          length = len;
      }
 
      void setBreadth( double bre )
      {
          breadth = bre;
      }
 
      void setHeight( double hei )
      {
          height = hei;
      }
      // 重載 + 運算符,用於把兩個 Box 對象相加
      Box operator+(const Box& b)
      {
         Box box;
         box.length = this->length + b.length;
         box.breadth = this->breadth + b.breadth;
         box.height = this->height + b.height;
         return box;
      }
   private:
      double length;      // 長度
      double breadth;     // 寬度
      double height;      // 高度
};
// 程序的主函數
int main( )
{
   Box Box1;                // 聲明 Box1,類型爲 Box
   Box Box2;                // 聲明 Box2,類型爲 Box
   Box Box3;                // 聲明 Box3,類型爲 Box
   double volume = 0.0;     // 把體積存儲在該變量中
 
   // Box1 詳述
   Box1.setLength(6.0); 
   Box1.setBreadth(7.0); 
   Box1.setHeight(5.0);
 
   // Box2 詳述
   Box2.setLength(12.0); 
   Box2.setBreadth(13.0); 
   Box2.setHeight(10.0);
 
   // Box1 的體積
   volume = Box1.getVolume();
   cout << "Volume of Box1 : " << volume <<endl;
 
   // Box2 的體積
   volume = Box2.getVolume();
   cout << "Volume of Box2 : " << volume <<endl;
 
   // 把兩個對象相加,獲得 Box3
   Box3 = Box1 + Box2;
 
   // Box3 的體積
   volume = Box3.getVolume();
   cout << "Volume of Box3 : " << volume <<endl;
 
   return 0;
}

總結

我真心以爲不少學生說C++難不是由於C++真的難,而是這種高自由的語法,很難讓一個初學者學生去掌握。對於學生來講最好先規範計算機的思惟而後再學習C++,同時推薦你們去學Java。找工做簡單,語言簡單。

而要說精通C++我以爲至少要把GCC 或者Clang 都學個精通才算精通吧。畢竟語言的使用只是語言的一部分。

相關文章
相關標籤/搜索