带继承的C ++ Builder模式

时间:2013-07-09 17:32:30

标签: c++ c++builder builder builder-pattern

我有一个类我想使用构建器模式,但它是从我需要访问其属性的基类派生的。即使我从BaseClass或同样臭的东西派生出构建器,我也无法在我的实现中访问BaseClass的成员而不公开它们。我的课程:

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指针或对象访问#34;。我试图摆弄Builder friend BaseClass,但无济于事。这个post也提供了一种解决方法,但它适用于Java,而且非常混乱。

在C ++中使用带继承的构建器模式是否有合适的方法?

2 个答案:

答案 0 :(得分:3)

即使在Builder内宣布了DerivedClassBuilder也不会与DerivedClass隐含的朋友一样,就像您期望的那样。 Builder仍然是它自己的类,它遵循与任何其他类相同的规则,包括范围访问规则。这就是DerivedClass默认无法访问protected Builder成员的原因。你需要明确宣布这种友谊。

此外,由于Builder::Description()没有Builder成员,因此description方法无法按原样运作。 this方法内的Builder指针仍然引用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
}

答案 1 :(得分:2)

请勿尝试直接访问该成员。使用公共访问方法。