2017-01-10 63 views
-2

我想阻止任何東西,但我的類的工廠從構建我的類的類型的對象。我需要這個類有一個公共接口,但我想限制它的創建只有它的工廠。我怎麼做?如何將一個類的構造函數的調用限制爲其工廠類?

我們稱之爲類Car和工廠CarFactory。下面是我如何做到這一點最初的想法,而無需使用friend和公開所有私有成員工廠:

class Car { 
private: 
    Car(); 
    Car(Car& ref); 

    friend class CarFactory; 
}; 

class CarFactory { 
public: 
    Car * makeCar(); 
}; 

我發現一個Java相關的問題:How do I make a constructor available to only the factory class?

上面的代碼工作原樣。爲了澄清,我想知道是否有辦法只與工廠共享構造函數,而不是所有的私有成員?

+0

這幾乎可以正常工作。預期和觀察到的行爲是什麼? –

+4

在陳述的最後添加問號並不能提供有用的問題嗎? –

+0

它的工作原理是,我不確定是否是限制訪問工廠類的正確方法。有沒有辦法做到這一點,而不將Car類的所有私有成員暴露給CarFactory類? – tylerjw

回答

3

從您的意見,我假定你正在尋找一個朋友的功能。幫助宣佈朋友可以找到here。這裏是你的例子修改。

// Forward declare car 
class Car; 

class CarFactory { 
public: 
    Car * makeCar(); 
    Car * makeTruck(); 
}; 

class Car { 
private: 
    Car(); 
    Car(Car& ref); 

    friend Car * CarFactory::makeCar(); 
}; 

Car * CarFactory::makeCar() { 
    return new Car(); 
} 

Car * CarFactory::makeTruck() { 
    return new Car(); // Fails to compile 
} 

編輯:您在評論中詢問了解決方案,只有Car的構造函數可用於工廠。您需要定義一個新的實用程序類,該實用程序類只能用於您想要的方法,然後使用該類來處理您希望保護的每種方法。我個人覺得這種方法笨重,但它的工作原理。

class Car { 

public: 
    struct t_private{ 
    private: 
     t_private() = default; 
     friend Car * CarFactory::makeCar(); 
    }; 

    Car(t_private); 

private: 
    Car(Car& ref); 
}; 

Car * CarFactory::makeCar() { 
    return new Car(Car::t_private{}); 
} 

只有CarFactory可以構建一個Car,因爲沒有其他人可以做出Car::t_private,因爲它的構造函數是私有的。 CarFactory由於不是朋友,因此無法訪問Car的私人會員。

+0

我被撕裂了,因爲這很直觀,而且很有用,但不是我問到的限制(這可能是不可能的)。我想知道是否有辦法讓Car to CarFactory的構造函數可用。這使得CarFactory :: makeCar()可以使用Car的所有私有成員。 – tylerjw

+0

@tylerjw查看編輯答案。 –

+1

@tylerjw我會與上述,但...插入另一層抽象。 'Car'是'CarFirewall'的朋友。'CarFirewall'只包含一個調用'Car'構造函數的方法。 'CarFirewall'是'CarFactory'的好友......好的。沒關係。弗朗索瓦安德列克斯剛剛做了這個。 – user4581301

-1

Car一個抽象類,然後實現它的工廠裏面的私有類:

class Car { 
    public: 
    virtual void drive()=0; 
}; 
class CarFactory { 
    private: 
    class CarImp : public Car { 
     ... 
    }; 
    public: 
    Car *makeCar() { return new CarImp(); } 
} 
+0

雖然這在技術上是正確的,並且會按照我的要求將構造函數放在工廠專用的實現中,但它看起來不直觀。您正在使用不能構建抽象對象並將其作爲工廠的私有成員進行子類化的副作用。 – tylerjw

+0

這不是不直觀的,這是隱藏所有實現並讓用戶只能看到接口的好方法。一般認爲是一種良好的做法。它具有不使用朋友關係的好處(在許多方面這是有問題的)。 –

相關問題