2010-02-16 153 views
4

對於類和指針,我有一個(對於C++程序員比我更好)的簡單問題。 我想過發表描述我的問題的示例代碼,但我發現用單詞解釋它比較容易。C++指向類實例的指針

假設我有三個類:阿

  • 類別:主類 - 它包含兩個BC的一個實例。
  • B類:該類包含一個輸出字符串的方法,稱之爲Greet()
  • C類:這一個也有一個方法,但該方法必須在位於類AB的實例中調用Greet()。我們來命名它DoSomethingWithB()

所以程序啓動時,在主函數中我創建了一個A的實例。 A再次創建BC的實例。然後,A呼叫C.DoSomethingWithB();

並且我的問題開始出現:我無法從C中訪問B

很顯然,我需要一個指針傳遞給BDoSomethingWithB()函數,這樣我可以叫B.Greet()C

龍解釋,簡短的問題:我如何做到這一點?

示例代碼來電:

#include <iostream> 
using namespace std; 

class B 
{ 
public: 
    void Greet() 
    { 
     cout<<"Hello Pointer!"<<endl; 
    } 
}; 

class C 
{ 
public: 
    void DoSomethingWithB() 
    { 
     // ... b.Greet(); Won't work obviously 
    } 
}; 

class A 
{ 
public: 
B b; // Not caring about visibility or bad class/variable names here 
C c; 
void StartTest() 
{ 
     c.DoSomethingWithB(); 
} 
}; 

int main() 
{ 
    A mainInstance; 
    mainInstance.StartTest(); 
} 

回答

8

難道你簡單地傳遞一個指針或引用他B反對呢?

class C 
{ 
public: 
    void DoSomethingWithB(B& b) 
    { 
     b.Greet(); // will work fine 
    } 
}; 

class A 
{ 
public: 
B b; // Not caring about visibility or bad class/variable names here 
C c; 
void StartTest() 
{ 
     c.DoSomethingWithB(b); 
} 
}; 

如果DoSomethingWithB()功能將無法修改B實例過去了,你應該標記參考const因此它可以用const B對象調用(例如,如果擁有A對象恰好是const) :

void DoSomethingWithB(B const& b); 

您有怎樣的B對象傳遞給函數的幾個選項:

  • 作爲參考(void DoSomethingWithB(B& b))它將讓函數修改傳入的對象。更改將在傳入的對象中被重新引用。

  • const引用(void DoSomethingWithB(B const& b)),這不會讓函數修改傳入的對象(除非是常量性拋棄 - 的東西,如果對一個對象完成這可能會導致不確定的行爲是忠實地const

  • 作爲指針或const指向B對象(void DoSomethingWithB(B* b)void DoSomethingWithB(B const* pb))的指針。這些函數與傳遞引用類似,但函數可以傳遞一個需要正確處理的NULL指針(在這種情況下不要取消引用)。另外,函數的調用將需要稍微改變傳遞B對象的地址:

    c.DoSomethingWithB(&b); 
    
  • 作爲通按值參數(void DoSomethingWithB(B b))。這有一個區別,即函數可以做任何喜歡的傳入的對象,它不會影響最初傳遞的對象,因爲函數正在處理副本。缺點是傳遞參數會導致複製,這可能是昂貴的。您也可以傳遞const值,但幾乎沒有建議通過const參考。

請注意,當選擇參數傳遞方法時,您應該首先根據您需要的功能(或不做)的語法選擇。後期擔心效率。始終首先設計和編寫正確的代碼 - 只有在設計和代碼正確之後才需要考慮效率。

+0

這就是我正在尋找的,還不太熟悉指針。這是最有效的方法嗎? – lamas 2010-02-16 17:18:46

+2

我也在這裏提到** const **引用,只是爲了顯示該選項。 – 2010-02-16 17:19:35

+0

我不確定我是否錯過了一些東西,因爲你的問題包含了一些關於課堂使用和可見性的知識;這似乎過於直接的答案。但每個人都需要從頭開始學習;這只是這個問題似乎表明,可能還有更多。 – 2010-02-16 17:22:50

-1
class C 
{ 
public: 
    C (B & b) : b(b) {} 
    void DoSomethingWithB() 
    { 
     // ... b.Greet(); Use b; 
    } 
private: 
    B & b; 
}; 

class A 
{ 
public: 
B b; // Declare b before c! 
C c; 
A() : c (b) {} 
void StartTest() 
{ 
     c.DoSomethingWithB(); 
} 
}; 
2

你可以做到這一點,就像你說的 - 傳遞一個指針(或參考)在向B DoSomethingWithB()

class C 
{ 
public: 
    void DoSomethingWithB(B & bInstance) 
    { 
     bInstance.Greet(); // should work fine! 
    } 
}; 

然後你就調用它像這樣:

class A 
{ 
public: 
    B b; // Not caring about visibility or bad class/variable names here 
    C c; 
    void StartTest() 
    { 
     c.DoSomethingWithB(b); 
    } 
}; 

我建議在這裏使用參考方法而不是指針,因爲:

  1. 您的對象是一個自動類成員,而
  2. 將null B對象傳遞給函數在這種情況下沒有意義。
3

更改的功能爲以下:

void DoSomethingWithB(B& b) 
{ 
    b.Greet(); 
} 

...和在甲...

c.DoSomethingWithB(b); 
0

在類C,聲明這樣的方法DoSomethingWithB():

void DoSomethingWithB(B* b) 
{ 
    b->Greet(); 
} 

而在A級調用它是這樣的:

void StartTest() 
{ 
    c.DoSomethingWithB(&b); 
} 

既然你提到了指針,我回答了使用指針。但是,在C++中,您應該儘可能使用const引用。這當然需要一個小的變化,以現有的代碼:

void DoSomethingWithB(const B& b) 
{ 
    b.Greet(); 
} 

// and 

void StartTest() 
{ 
    c.DoSomethingWithB(b); 
} 
0

我不能從C內

訪問而不必在B C調用方法,爲什麼不能有Ç說明B將信息返回給調用者,以便它可以執行操作?

當我碰到這些時,我發現這是因爲我的課程組織得不好。通常情況下,如果我重新考慮這個問題,新的組織會消失。