带有继承的C++Builder模式

C++ Builder Pattern with Inheritance

本文关键字:C++Builder 模式 继承      更新时间:2023-10-16

我有一个类想要使用构建器模式,但它是从一个基类派生的,我需要访问该基类的属性。在我的实现中,如果不公开BaseClass的成员,我就无法访问它们,即使我从BaseClass或类似的东西派生Builder也是如此。我的课程:

基本类.h:

class BaseClass
{
    protected:
        CString name;
}

衍生类.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指针或对象访问"。我试着把Builder变成BaseClassfriend,但没有成功。这篇文章也提供了一个变通方法,但它是针对Java的,而且非常混乱。

在C++中,有没有一种体面的方法可以使用带有继承的构建器模式

尽管Builder是在DerivedClass内部声明的,但Builder并不像您所期望的那样与DerivedClass隐式地成为朋友。Builder仍然是它自己的类,并且它遵循与任何其他类相同的规则,包括作用域访问规则。这就是DerivedClass默认情况下不能访问Builderprotected成员的原因。你需要明确地宣布这种友谊。

此外,由于Builder没有description成员,您的Builder::Description()方法将无法按原样工作。Builder方法内部的this指针仍然指向Builder实例,而不是DerivedClass实例。如果希望Builder访问DerivedClass的成员,则需要为其提供一个指向DerivedClass实例的指针。否则,给Builder它自己的description成员(看起来你无论如何都在尝试这样做)。

试试这个:

基本类.h:

class BaseClass
{
protected:
    CString name;
};

衍生类.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
}

不要试图直接访问成员。使用公共访问器方法。