C++ Builder Pattern with Inheritance
builder, builder-pattern, c++, c++builder
Solution
Even though `Builder` is declared inside of `DerivedClass`, `Builder` is not implicitly friends with `DerivedClass`, like you are expecting. `Builder` is still its own class, and it follows the same rules as any other class, including scope access rules. That is why `DerivedClass` cannot access `protected` members of `Builder` by default. You need to explicitly declare that friendship.
Also, your `Builder::Description()` method will not work as-is because `Builder` does not have a `description` member. The `this` pointer inside of `Builder` methods still refers to the `Builder` instance, not a `DerivedClass` instance. If you want the `Builder` to access members of `DerivedClass`, it needs to be given a pointer to a `DerivedClass` instance. Otherwise, give `Builder` its own `description` member (which it looks like you were attempting to do anyway).
Try this:
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
}
Problem
I have a class I would like to use the builder pattern on, but it is derived from a base class whose attributes I need to access. I can't access the members of `BaseClass` in my implementation without making them public, even if I derive Builder from `BaseClass` or something equally smelly. My classes: 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 } ``` My problem is that I can't access `builder.name`. Visual Studio says that "protected member `BaseClass::name` is not accessible through a `DerivedClass::Builder` pointer or object". I've tried fiddling around with making `Builder` a `friend` of `BaseClass`, but to no avail. This post has also provided a workaround, but it's for Java, and very messy. Is there a decent way to use the builder pattern with inheritance in C++?