C ++ Builder — C ++ Builder Pattern с наследованием

У меня есть класс, на котором я хотел бы использовать шаблон построителя, но он получен из базового класса, к атрибутам которого мне нужно получить доступ. Я не могу получить доступ к членам BaseClass в моей реализации, не делая их общедоступными, даже если я выведу Builder из 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 указатель или объект «. Я пытался возиться с созданием Builder friend из BaseClass, но безрезультатно. это сообщение также предоставил обходной путь, но это для Java, и очень грязный.

Есть ли достойный способ использовать шаблон построителя с наследованием в C ++?

3

Решение

Даже если Builder объявлен внутри DerivedClass, Builder неявно дружит с 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
}
3

Другие решения

Не пытайтесь получить доступ к члену напрямую. Используйте метод публичного доступа.

2

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector