2012-02-21 72 views
3

我有一些關於C++開發人員有關C++的問題。有關C++開發人員有關C++的一些問題

因爲幾天我在看一些C++代碼,我有folwing問題:

  1. 什麼時候使用Foo::Foo.Foo->
  2. 什麼時候使用一個真正的構造函數,並在剛String a;(有時我需要做的某事物一樣String a("foo");
  3. 哪裏是這些簽名的區別是:int foo(int a)int foo(int &a)
+0

你試過Google搜索這個問題嗎? – triclosan 2012-02-21 09:33:09

+2

我建議你在C++初學者書上投資,因爲所有這些(以及更多)都應該在其中解釋。 – 2012-02-21 09:34:10

+0

@triclosan:爲什麼這很重要? Google是比尋求編程答案更好的地方嗎? – jalf 2012-02-21 10:17:30

回答

5

::被使用,也可以顯式地指定一個命名空間(std::string,例如,String類的命名空間std),或靜態成員一類。

.在C#中使用得很多,指的是類的成員。

->與指針一起使用。如果p是指向對象obj的指針,則p->x具有與obj.x相同的含義。

我什麼時候使用真正的構造函數,何時只是String a; (有時我需要做一些像String a(「foo」);)

當你需要。String a大致相當於的a = new String()(需要提醒的是,如果String是一種非POD類型,它可能包含未初始化的成員。)

C#如果你需要a初始化爲一個特定的值,你這樣做。 (具有String a("foo"),或與String a = "foo"

其中是這些簽名之間的差值:INT FOO(INT一個)和int foo的(INT &一個)?

&表示參考。這不是相當於一個C#的引用,但也有相似之處。在C#中,你有值類型和引用類型,並且引用類型總是按引用傳遞。

在C++中,沒有這樣的區別。每種類型都可以通過價值或參考傳遞。類型T&是參考T的。換句話說,給定以下代碼:

void foo(int& j); 
void bar(int j); 

int i = 42; 

foo(i); 
bar(i); 

foo將得到i一個參考,這意味着它可以修改的i值。 bar將獲得副本i,這意味着它所做的任何修改都不會反映在i中。

您經常使用const T&(對const T的引用)作爲避免複製的方式,同時仍阻止被調用者修改該對象。

0
  1. Foo:: - 靜態方法

    Foo. - 當你有一個棧對象實例實例方法。 (MyObject obj

    Foo-> - 實例方法,當你有一個對象指針。 (MyObject* pObj = new MyObject()

  2. 每當你需要傳遞一些值給構造函數。

  3. int&是對int的參考。 a範圍內的任何更改將影響a以外的方法。 (相當於ref在C#)

+1

還請記住,操作員可能會過載。 – Nick 2012-02-21 09:39:47

2

1:假設你要調用方法

美孚:: theMethod(...)

打電話時爲實施例中使用一類Foo的靜態方法

Foo.theMethod(...)

是當你有一個名爲美孚

Foo-> theMethod(對象...)

是當你有一個指針的名爲Foo

2目的:

字符串一個;

調用默認的構造函數,它沒有參數

字符串一( 「富」)

調用一個重載的構造

3:

INT foo(int & a)

需要對整數進行引用,所以在該方法中您可以操縱一個。

INT FOO(INT A)

進行復印時,操縱它不會有在離開方法之後經過在實際參數的任何影響。

1
  1. String a:構建一個空String對象

    String a("foo"):構建initalized到"foo"

  2. int foo(int a)一個String對象:通過值傳遞a /複製到FOO。裏面FOO如果修改aa不會外富

    int foo(int& a)受到影響:由內而外foo的引用傳遞a。如果修改aa也將修改後富結束

2

問題1:

這取決於什麼Foo是。運算符::被稱爲範圍 解析運算符;右邊的操作數必須是一個名稱空間或一個類,而左邊的操作數是名稱空間或類的成員。 如果Foo是一個類,Foo::可用於訪問靜態成員,或 從派生類的構件內,以訪問 基類的成員:例如:

class Foo 
{ 
public: 
    virtual void f(); 
    static void g(); 
}; 

int h() 
{ 
    Foo::g(); 
} 

class Derived : public Foo 
{ 
public: 
    virtual void f() 
    { 
     Foo::f(); // Call function in base class... 
    } 
} 

它通常使用也可以訪問命名空間成員,例如std::cout (名稱空間std中的cout對象)。

.運算符是成員訪問運算符,並且需要一個對象(或對對象的引用)作爲左手操作數。因此,(使用上述 定義):

Foo obj; 
obj.f(); 

void i(Foo& rFoo) 
{ 
    rFoo.f(); 
} 

它也可以用於訪問靜態成員,如果你有一個實例:

Foo obj; 
obj.g(); 

->是非常像.運營商,除了它指向一個實例,而不是一個實例,並且(非常重要的) 指針可能會被重載。因此:

Foo* obj; 
obj->g(); 
// And if Ptr is a user defined type with an overloaded 
// `operator->` which returns a Foo* 
Ptr obj; 
obj->g(); 

同樣,你也可以使用這個語法來訪問靜態成員,如果你 有一個指向對象。

問題2:

String a;呼籲一個真正的構造函數的定義。當你想要默認的構造函數時使用String a;;沒有參數的那個。 當你想構造函數採用 char const*(或char const (&)[4],但這是不太可能的,因爲它 將只適用於具有三個字符的字符串文字)的構造函數時使用String a("foo");

通常,定義當變量:

String a;    // default constructor... 
String a1();   // NOT what it looks like: this is a 
         // function declaration, and not the 
         // definition of a variable!!! 
String b(x, y, z); // constructor taking x, y and z as arguments... 
String c = x;   // implicitly convert `x` to String, then 
         // copy constructor. 

最後一種形式是有點麻煩,因爲拷貝構造可以是(並 幾乎總是)消隱,但該程序的合法性是由下式定義 上面的規則:必須有一種方法,將x隱式轉換爲 String,並且String必須具有可訪問的拷貝構造函數。

在其他情況下,例如new String(),空參數 的形式可用於「值構造」,如果存在用戶定義的一個,則默認構造函數 ,否則爲零初始化。

問題3:

第一種是通過值傳遞,並傳遞參數的副本到 功能。第二種是通過引用,並將參考 (其行爲有點類似於隱藏的,自動取消引用的指針)到該函數。因此:

void f(int a) 
{ 
    ++ a;  // Modifies local copy, has no effect on the argument. 
} 

void g(int& a) 
{ 
    ++ a;  // Modifies the variable passed as an argument. 
} 

請注意,在第一種情況下,您可以傳遞任意表達式;在 第二,你必須通過一些東西,稱爲左值—即 你可以使用類似的表達式(一個名爲 變量,或一個取消指針,或命名數組中的元素, 等)後訪問的東西。