У меня есть класс, на котором я хотел бы использовать шаблон построителя, но он получен из базового класса, к атрибутам которого мне нужно получить доступ. Я не могу получить доступ к членам 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 ++?
Даже если 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
}
Не пытайтесь получить доступ к члену напрямую. Используйте метод публичного доступа.