我应该如何处理只能由工厂类使用的setter方法
How should I handle setter methods that shoud only be used by the factory class?
我正在使用一个工厂类从内存池中生成许多小类。这些小类一旦被工厂退回就保持不变。
目前,其中一个小对象的典型声明如下:
class LittleObject
{
public:
...//non-getter and setter member functions
int getMemberVariable1() const;//should be accessible to everyone
void setMemberVariable1(int newMemberVariable1Value);//should only be accessible to factory class
...//more getters and setters
private:
...
};
所以,正如你所看到的,getter和setter都在公共区域。但是,唯一应该设置值的时间是在工厂类构建它的期间。现在,我可以清楚地看到一个选项,将setter函数移到私有访问,并使工厂成为LittleObject类的朋友。我觉得这个选项有点不雅,因为它向工厂公开了其他私有成员函数。工厂无权访问的私有成员功能。
所以我的问题是:最好的方法是什么,这样只有工厂类才能使用setter函数
我会使用friend class
:
class LittleObject
{
friend class LittleObjectFactory;
public:
int getMemberVariable();
private:
void setMemberVariable( int value );
};
我真的更喜欢friend
工厂,但如果你需要更强的
封装,以牺牲优雅为代价,可能可以实现
struct LittleData;
class Factory
{
public:
void MakeLittle(LittleData&);
};
struct LittleData
{
int data1;
float data2;
};
class LittleObject
{
public:
LittleObject(const LittleObject&) = default;
LittleObject& operator=(const LittleObject&) = default;
int GetData1() const { return data.data1; }
float GetData2() const { return data.data2; }
static LittleObject MakeOne( Factory& f )
{
LittleObject obj;
f.MakeLittle(obj.data);
return obj;
}
private:
LittleObject();
LittleData data;
};
看看我刚刚写的。。。我真的更喜欢friend
另一种可能性是模板。
我的意思是,每个LittleObject
的静态实例都预设为所需的配置,因此工厂只需要制作一个副本。
复制可以通过复制构造函数进行,或者,如果您不想创建其中一个(并且对象很琐碎),则可以使用memcpy()
。
下面是一个使用复制构造函数的示例:
class LittleObject1
{
int a;
int b;
public:
LittleObject1(const LittleObject1& o): a(o.a), b(o.b) {}
LittleObject1(int a = 0, int b = 0): a(a), b(b) {}
static LittleObject1 stencil;
int get_a() const { return a; }
int get_b() const { return b; }
};
LittleObject1 LittleObject1::stencil(3, 7); // preset values
class LittleObject2
{
std::string s;
public:
LittleObject2(const LittleObject2& o): s(o.s) {}
LittleObject2(const std::string& s = ""): s(s) {}
static LittleObject2 stencil;
std::string get_s() const { return s; }
};
LittleObject2 LittleObject2::stencil("hello"); // preset values
class Factory
{
public:
template<typename Type>
Type* create() const
{
return new Type(Type::stencil); // make a copy of the preset here
}
};
int main()
{
Factory fact;
LittleObject1* o1 = fact.create<LittleObject1>();
std::cout << o1->get_a() << 'n';
std::cout << o1->get_b() << 'n';
LittleObject2* o2 = fact.create<LittleObject2>();
std::cout << o2->get_s() << 'n';
}
只有当值是预设的并且不需要在运行时进行计算时,这才有用。
依赖常量正确性
你说这些对象在工厂返回时是恒定的。既然如此,为什么不直接返回const
对象:
class Factory
{
public:
std::unique_ptr<const DynamicLittleObject> createDynamicLittleObject();
const AutomaticLittleObject createAutomaticLittleObject();
};
然后,只要确保以常量正确的方式编写它们的功能,就会提供正确的访问控制。
有些人可能会担心用户可能会消除恐慌,但为了保护他们免受伤害,只有这么多值得做的事情。
您可以使工厂成为每个对象的静态成员函数。因此,每个对象类型都知道如何创建自己。然后,您可以使用某种模板函数来减少创建它们的键入。
有点像这样:
class LittleObject1
{
int a = 0;
int b = 0;
public:
virtual ~LittleObject1() {}
static LittleObject1* create()
{
LittleObject1* o = new LittleObject1;
o->a = 1;
o->b = 2;
return o;
}
};
class LittleObject2
{
std::string s;
public:
virtual ~LittleObject2() {}
static LittleObject2* create()
{
LittleObject2* o = new LittleObject2;
o->s = "hello";
return o;
}
};
template<typename Type>
Type* createType(Type*)
{
return Type::create();
}
int main()
{
LittleObject1* o1 = createType(o1);
LittleObject2* o2 = createType(o2);
}
- 如何在工厂方法中返回指向基于基础操作系统的派生类的有效指针
- 工厂方法:分配和strcpy_s的差异
- 在基类中编写工厂方法
- 从工厂方法返回的ComPtr的引用计数增加两次
- 工厂方法模式使用继承而抽象工厂模式使用组合如何
- 在C++中将返回unique_ptr和shared_ptr的两个工厂方法组合为一个
- 工厂方法中的访问冲突
- 如何模板静态工厂方法?
- 工厂方法创建的对象应该在哪里删除?
- 如何禁用在工厂方法之外创建/复制 obj?
- 为 STL 随机数生成器编写工厂方法
- 此工厂方法是否会导致争用条件?
- 如何从JSON String创建工厂方法
- C++可扩展的工厂方法
- 总结工厂方法
- 对不同的参数使用工厂方法模式
- 使用工厂方法时编译器错误:无法转换"const std::p air<char* const
- Boost::log 使用静态工厂方法
- 如何使用工厂方法创建不同的对象
- 我可以有一个仅使用工厂方法创建的成员变量吗?