2013-07-09 132 views
3

我有一個類,我想使用生成器模式,但它是從我需要訪問的屬性的基類派生的。即使我從BaseClass或其他同樣臭的東西中派生出Builder,我也無法在我的實現中訪問BaseClass的成員。我的課:繼承的C++ Builder模式

BaseClass.h:

class BaseClass 
{ 
    protected: 
     CString name; 
} 

DerivedClass.h:

class DerivedClass : public BaseClass 
{ 
    public: 
     // builder starts here and has the same base class as the class it is nested in 
     // (if it doesn't, we can't get access to name) 
     static class Builder : public BaseClass 
     { 
      public: 

       Builder::Builder(CString pName) 
       { 
        this->name = pName; 
       } 

       Builder Builder::Description(CString pDescription) 
       { 
        this->description = pDescription; 
        return *this; 
       } 
     }; 

    public: 
     CString description; 
}; 

DerivedClass.cpp:

DerivedClass::DerivedClass(Builder builder) 
{ 
    this->name = builder.name; // this is NOT ok 
    this->description = builder.description; // this is ok 
} 

我的問題是,我無法訪問builder.name 。 Visual Studio說「受保護的成員BaseClass::name不能通過DerivedClass::Builder指針或對象訪問」。我已經嘗試做的BaseClass擺弄,但無濟於事。這個post也提供了一個解決方法,但是它對於Java而言非常混亂。

是否有一個體面的方式來使用C++繼承構造模式?

回答

3

即使BuilderDerivedClass內宣告,但Builder並不隱含爲DerivedClass的朋友,就像您所期待的那樣。 Builder仍然是它自己的類,它遵循與任何其他類相同的規則,包括範圍訪問規則。這就是爲什麼DerivedClass默認情況下無法訪問Builderprotected成員。你需要明確宣佈這種友誼。

此外,您的Builder::Description()方法將無法正常工作,因爲Builder沒有description成員。 Builder方法中的this指針仍指Builder實例,而不是DerivedClass實例。如果您希望Builder訪問DerivedClass的成員,則需要爲其指定一個指向DerivedClass實例的指針。否則,請給Builder自己的description成員(它看起來像是你試圖做的那樣)。

試試這個:

BaseClass.h:

class BaseClass 
{ 
protected: 
    CString name; 
}; 

DerivedClass.h:

class DerivedClass : public BaseClass 
{ 
public: 
    class Builder : public BaseClass 
    { 
    public: 
     Builder(const CString &pName) 
     { 
      this->name = pName; 
     } 

     Builder& Description(const CString &pDescription) 
     { 
      this->description = pDescription; 
      return *this; 
     } 

    public: 
     CString description; // <-- add this 

    friend class DerivedClass; // <-- add this 
    }; 

public: 
    DerivedClass(const Builder &builder); 

public: 
    CString description; 
}; 

DerivedClass.cpp:

DerivedClass::DerivedClass(const DerivedClass::Builder &builder) 
{ 
    this->name = builder.name; // this is ok now 
    this->description = builder.description; // this is ok now 
} 
+0

這看起來正是我在找的東西,謝謝! – aguazales

+0

訪問規則已在C++ 11中更新。嵌套類現在可以訪問封閉類可以訪問的所有名稱(請參見[this](http://en.cppreference.com/w/cpp/language/nested_types))。 – Excambion

2

不要試圖直接訪問該成員。使用公共訪問器方法。

+0

但是,如果該成員只'受保護「,我不應該直接訪問它因爲我的'Builder'是從成員存儲在'BaseClass'中的? – aguazales

+0

我想我只想知道爲什麼我可以在頭文件中訪問成員,但不在cpp文件中。 – aguazales