一個完整的C++程序包括頭文件(.h)和文本文件(.cpp).當然兩者都不是必須存在的.只要有其中之一就可以.
1.C++使用#include預處理器指示符來將頭文件引入而成為我們程序的一部分.它將讀入指定文件的內容,有兩種格式
#include <some_file.h>
#include "my_file.h"
我們可以把用"<"和">"引入的頭文件理解成是一個工程或者標準頭文件(系統提供的).查找過程會檢查預定義的目錄.
而用引號括起來則表明該文件是用戶提供的頭文件.查找將從當前文件目錄開始.
這個include我覺得類似于JAVA的import
2.注釋方法一樣
3.類文件的定義.嚴格來說并沒有類文件的說法.我是為了和普通的cpp文件區分開來才這么說的.C++中類的聲明寫在頭文件中
聲明一個類:
class test{
public:void test1();
private:void test2();
};
注意這里的寫法.最后那個大括號后面必須要跟一個分號的.JAVA則不用.我一開始及其不適應.
然后在cpp文件中來定義
void test::test1(){
cout << "aaa";
}
void test::test2(){
cout << "bb";
}
注意:這里大括號后面有沒有帶分號都沒關系.
4.C++中對函數的調用方法也靈活.
test t;
t.test2();
----------------
test* t = new test();
t->test2();
其實我還是喜歡test t = new test();t.test2()
5.編譯器的解析.如果沒有引入頭文件的話你必須把main()函數放到文件的最下面.
void main(){
test();
}
void test(){
cout << "aa";
}
這樣寫編譯器會報找不到test()方法的.這個是C遺留下的問題.解決方法就是引入頭文件,或者把main寫到最后.或者在main前面聲明一下:
void test();
void main(){
test();
}
void test(){
cout << "aa";
}
這種做法就和引入頭文件差不多了.
6.析構函數.這個特性很有用,在類消失的最后一刻自動調用這個種類型的函數來做一些清除操作
7.爭議比較大的聲明指針類型.
int* pt=0;
int *pt=0;
這個星號是緊跟著類型呢還是緊跟著變量名呢.由于C++的靈活度太高.這兩種寫法都沒錯誤.但按理來說緊跟著類型應該會好一些.因為我們是在聲明一個指針類型的變量.但如果按下面的寫法:
int* pt,pt1;
你說pt1是指針類型嗎,答案是不是.遇到這種情況就要把*號緊跟著變量名了
int *pt,*pt1;
耐心點,接下來的是精華
main 函數
C++
//自由浮動的函數
int main( int argc, char* argv[])
{
printf( "Hello, world" );
}
Java
// 每個函數(方法)都必須是一個類的一部分;當java <class>運行是一個特定類的主函數會被調用
// (因此你可以讓每個類都有一個main函數,這在寫單元測試是很有用)
class HelloWorld
{
public static void main(String args[])
{
System.out.println( "Hello, World" );
}
}
類的聲明
除了 Java 不要求用分號外幾乎是相同的。
C++
class Bar {};
Java
class Bar {}
方法聲明
都相同的, 除了在Java,方法必須總是某個類的一部分并且可能public/private/protected 作為修飾
構造函數和析構函數
構造函數都是相同的 (即類的名字), Java沒有準確意義上的的析構函數
靜態成員函數和變量
方法聲明是相同的, 但 Java 提供靜態初始化塊來來初始化靜態變量 (不需要在源文件中聲明):
class Foo
{
static private int x;
// 靜態初始化塊
{ x = 5; }
}
對象的聲明
C++
// 在棧中
myClass x;
//或者在堆中
myClass *x = new myClass;
Java
// 總是在對堆中聲明
myClass x = new myClass();
繼 承
C++
class Foo : public Bar
{ ... };
Java
class Foo extends Bar
{ ... }
訪問級別 (abstraction barriers)
C++
public:
void foo();
void bar();
Java
public void foo();
public void bar();
虛函數
C++
virtual int foo(); // 或者非虛函數寫作 int foo();
Java
// 函數默認的就是虛函數; 用final關鍵字防止重載
int foo(); // 或者, final int foo();
內存管理
大體上是相同的--new 來分配, 但是 Java沒有 delete,因為它有垃圾回收器。
NULL vs null
C++
// 初始化一個指針為 NULL
int *x = NULL;
Java
// 編譯器將捕獲使用未初始化的引用
//但是如果你因需要初始化一個引用而賦一個null,那么這是無效的
myClass x = null;
布爾型
Java有一點羅嗦: 你必須寫 boolean而不止是 bool.
C++
bool foo;
Java
boolean foo;
常 量
C++
const int x = 7;
Java
final int x = 7;
拋異常
首先,Java在編譯器強制拋異常—如果你的方法可能會拋異常你必需明確報告
C++
int foo() throw (IOException)
Java
int foo() throws IOException
數 組
C++
int x[10];
// 或
int *x = new x[10];
// 使用 x,然后歸還內存
delete[] x;
Java
int[] x = new int[10];
// 使用 x, 內存有垃圾回收器回收或
//或在程序生命周期盡頭歸還給系統
集合和迭代器
C++
迭代器是類的成員。范圍的開始是<容器>.begin(), 結束是 <容器>.end()。 用++ 操作符遞增, 用 *操作符訪。
vector myVec;
for ( vector<int>::iterator itr = myVec.begin();
itr != myVec.end();
++itr )
{
cout << *itr;
}
Java
迭代器只是一個接口。 范圍的開始是 <集合>.iterator,你必須用itr.hasNext()來查看是否到達集合尾。 使用itr.next()(是在C++中使用操作符++ 和*操作的結合)來獲得下一個元素。
ArrayList myArrayList = new ArrayList();
Iterator itr = myArrayList.iterator();
while ( itr.hasNext() )
{
System.out.println( itr.next() );
}
// 或, 在Java 5中
ArrayList myArrayList = new ArrayList();
for( Object o : myArrayList ) {
System.out.println( o );
}
抽象類
C++
// 只需要包含一個純虛函數
class Bar { public: virtual void foo() = 0; };
Java
// 語法上允許顯示的聲明!
abstract class Bar { public abstract void foo(); }
// 或者你也可以聲明一個接口
interface Bar { public void foo(); }
// 然后讓一個類繼承這個接口:
class Chocolate implements Bar
{
public void foo() { /* do something */ }
}
引用 vs 指針
C++
//引用不可改變,通過使用指針來獲得更多的靈活性
int bar = 7, qux = 6;
int& foo = bar;
Java
// 引用是可變的,僅存儲對象地址;
//沒有指針類型
myClass x;
x.foo(); // error, x is a null “pointer”
// 注意你要總是用 . 來訪問域
編 譯
C++
// 編譯
g++ foo.cc -o outfile
// 運行
./outfile
Java
// 編譯foo.java文件中的類成<classname>.class javac foo.java
// 通過調用<classname>中的靜態main方法來運行
java <classname>
注 釋
兩種語言是一樣的 (// 和 /* */ 可以用)