2011-05-15 88 views
1

在C++中可以使用以下設置/設計模式嗎?C++設計模式:可能有派生類的私有繼承方法?

  • 一個前導類
  • 一個Worker類
    • 具有方法M()
  • 一個MyWorker類(繼承工人)

前導類具有許多工人和需要從Worker類調用方法M()。但是,我不希望Worker(即MyWorker)的任何實現有權訪問方法M()。在這種情況下,公共,私人和保護似乎都不起作用。

該設置是否可行?或者我應該如何設計其他東西?

由於

編輯:(添加示例情況下)

假設M()是GiveMoney(),負責人= Parent和工人=兒童。我只希望父母能夠給孩子錢(和孩子不能給自己的錢)。

+3

你想一個類不能訪問它自己的方法,但該方法可以被調用從另一個類?我不認爲這是可能的任何語言。 – 2011-05-15 21:26:55

+0

郵政編碼,如果將M()定義爲私有;並通過公共擴展應該會導致MyWorker無法訪問私有方法。事實上,M()是私有的,只要Worker(M()的原始所有者)是調用M()的唯一東西,就可以正常工作,因爲通常情況下,實例可以對其他實例上的私有方法/成員進行操作同班。 – Suroot 2011-05-15 21:27:19

+0

如果'M()'被定義爲** private **並且'Leader'是'Worker'的一個朋友,那麼一切都應該如你所願地工作 - 如果我正確理解你的話。 – 2011-05-15 21:31:12

回答

0

像這樣:

#include <iostream> 

class Leader 
{ 
    private: 
    virtual char M() = 0; 
    public: 
    void foo() { std::cout << M(); } 
}; 

class Worker : public Leader 
{ 
    private: 
    virtual char M() { return 'm'; } 
}; 

然後

int main() 
{ 
    Worker w; 
    w.foo(); 
} 

打印m

class MyWorker : public Worker 
{ 
    void foo2() { std::cout << M(); } 
}; 

導致編譯錯誤,抱怨

'虛擬char Worker :: M()'是私有的。

+0

如果我不希望工人繼承領導者,該怎麼辦?舉個例子,假設方法是AddFood(),我不希望工人能夠自己餵養。 – Fred14 2011-05-15 21:39:41

+0

然後你必須讓'Worker'成爲Leader的一個朋友,否則你必須重寫Leader,這樣它不必調用Worker :: M(例如通過移動需要調用的函數到'Worker'類(但在您的特定情況下可能不適合))。 – Oswald 2011-05-15 21:42:34

1

你既可以:

  1. 請在WorkerM()一個私有函數,並宣佈Leader是的Worker的朋友。
  2. M()的邏輯從Worker中移出,並寫入Leader。就個人而言,這是我會採取的方法,因爲無論M()做什麼,你不希望任何其他Worker做。
0

你爲什麼要這麼做?你究竟在努力實現什麼?瞭解您的最終目標將幫助我們幫助您找到您要找的答案。

如果你想完全隱藏一些實現細節,最好的辦法是爲工作人員的公共部分製作一個獨立的基類,讓你的私人工作者通過構圖來包含公共位。

編輯聽起來像是你讓生活變得不必要的困難。除非有其他人控制了童工的實施,爲什麼不避免叫童工給錢呢?

像這樣的事情可能會爲您的工作例如:

class Parent // Leader 
{ 
private: 
    Child* m_pChildren; 
}; 

class Child : public ChildSelf 
{ 
public: 
    char GiveMoney() { return 'm'; } 
}; 

class ChildSelf 
{ 
    Run(); 
    Jump(); 
    ClimbTrees(); 
}; 

class MyChild : public ChildSelf 
{ 
    void RunFaster() { Run(); Run(); } 
}; 

你的孩子工作者的實現只能訪問ChildSelf它給你你正在尋找安全的水平..?

-1

聽起來像是你應該看看Visitor設計模式:http://en.wikipedia.org/wiki/Visitor_pattern

這是不完全一樣的方法,但我相信,如果你定義的Worker類的LeaderVisit(Worker)方法和Accept(Leader)方法則調用private M(),你可以得到你正在尋找的功能。

看到,因爲我的職位是downvoted我決定它可能會幫助,如果我給一點額外的信息:

class Leader; 

class Worker 
{ 
virtual void M() = 0; 
public: 
    void Accept(const Leader & w) 
     { 
      M(); 
     } 
}; 

class Leader 
{ 
public: 
void Visit (Worker & w) const 
    { 
    w.Accept(*this); 
    } 
}; 

class MyWorker : public Worker 
{ 
virtual void M() 
    { 
    std::cout << "M()" << std::endl; 
    } 
}; 


int main(int argc, char **argv) 
{ 
Leader l; 
MyWorker myW; 
myW.Accept(l) 
return 0; 
} 

M()堪稱是通過使用Leader的唯一途徑,Worker是一個抽象類,甚至無法實例化,但如果您願意,您可以爲M()提供默認行爲。

0

已有M私有,並聲明LeaderWorker的好友。您仍然可以實現MWorker派生類:

class Leader; 

class Worker 
{ 
    virtual void M() = 0; 
    friend class Leader; 
}; 

class Leader 
{ 
    Worker* w; 

public: 
    void doSomething() { w->M(); } 
}; 

class MyWorker : public Worker 
{ 
    void M() { ... } // No problem. Even if `M` is private in the base class, it 
        // can still be overridden, but not accessed. 
};