关于在C ++中组织班级成员(特别是有很多班级)的最佳方法的任何意见。特别是,一个类有很多用户参数,例如一个优化某些功能并具有多个参数的类,例如迭代次数,优化步骤的大小,使用的具体方法,优化函数权重等等。我尝试了几种通用的方法,似乎总能找到一些非理想的方法。它。只是好奇别人的经历。
更具体地说,我正在处理的代码跟踪一系列图像中的对象。所以一个重要的方面是它需要在帧之间保留状态(为什么我不只是制作一堆函数)。重要的成员函数包括initTrack(),trackFromLastFrame(),isTrackValid()。并且有一堆用户参数(例如,跟踪每个对象跟踪的点数,帧之间可以移动多少点,使用跟踪方法等等)
答案 0 :(得分:5)
如果您的课程 BIG ,那么您的课程 BAD 。 一个班级应该尊重Single Responsibility Principle,即:一个班级应该只做一件事,但应该做得好。 (“只有一个”是极端的,但它应该只有一个角色,而且必须明确实施。)
然后,您创建的类通过组合与这些单一角色的小类进行丰富,每个类都有一个清晰而简单的角色。
BIG函数和BIG类是嵌套的错误,误解和不必要的副作用(特别是在维护期间),因为NO MAN可以在几分钟内学会700行代码。
所以BIG课程的政策是:重构,小课程的作文只针对他们所做的事情。
答案 1 :(得分:3)
如果我必须选择您列出的四种解决方案之一:类中的私人课程。
实际上:你可能有重复的代码应该重复使用,你的类应该重新组织成更小,更合理和可重用的部分。正如GMan所说:重构你的代码
答案 2 :(得分:3)
首先,我将成员分为两组:(1)仅限内部使用,(2)用户将调整以控制类行为的那些。第一组应该只是私有成员变量。
如果第二个集合很大(或者因为你还在进行积极的开发而不断增长和变化),那么你可以将它们放入自己的类或结构中。然后,您的主要课程将有两种方法,GetTrackingParameters
和SetTrackingParameters
。构造函数将建立默认值。然后,用户可以致电GetTrackingParameters
,进行更改,然后拨打SetTrackingParameters
。现在,当您添加或删除参数时,您的界面将保持不变。
如果参数是简单和正交的,那么它们可以包含在具有良好命名的公共成员的结构中。如果存在必须强制执行的约束,尤其是组合,那么我将参数实现为具有每个参数的getter和setter的类。
ObjectTracker tracker; // invokes constructor which gets default params
TrackerParams params = tracker.GetTrackingParameters();
params.number_of_objects_to_track = 3;
params.other_tracking_option = kHighestPrecision;
tracker.SetTrackingParameters(params);
// Now start tracking.
如果您以后发明了一个新参数,您只需要在TrackerParams中声明一个新成员并在ObjectTracker的构造函数中初始化它。
答案 3 :(得分:2)
一切都取决于:
答案 4 :(得分:1)
听起来这可能是模板的工作,就像你描述用法一样。
template class FunctionOptimizer <typename FUNCTION, typename METHOD,
typename PARAMS>
例如,PARAMS
封装了简单的优化运行参数(迭代次数等),METHOD
包含实际的优化代码。 FUNCTION
描述了您要针对优化进行定位的基本功能。
关键不在于这是“最好”的方法,但是如果你的类非常大,那么它内部可能会有更小的抽象,它们可以自然地重构为一个不那么单一的结构。
但是你处理这个问题,你不必一次重构 - 从小处开始分段,并确保代码在每一步都有效。你会对你对代码的快速感受感到惊讶。
答案 5 :(得分:0)
我认为制作单独的结构来保存参数没有任何好处。该类已经是一个结构 - 如果它适合通过结构传递参数,那么将类成员公之于众也是合适的。
公共成员和Set / Get功能之间存在权衡。公共成员的模板很少,但它们暴露了类的内部工作。如果要从代码中调用它,如果重构类就无法重构,那么你几乎肯定会想要使用Get和Set。
答案 6 :(得分:0)
假设配置选项仅适用于此类,请使用由具有有意义的函数名称的公共函数操作的私有变量。 SetMaxInteriorAngle()
比SetMIA()
或SetParameter6()
好得多。使用getter和setter可以强制执行配置的一致性规则,并可用于补偿配置界面中的某些更改量。
如果这些是一般设置,由多个类使用,那么外部类最好,具有私有成员和适当的功能。
公共数据成员通常是一个坏主意,因为它们暴露了类的实现,并使它们之间不可能有任何保证关系。虽然我将它们分组在数据成员列表中并使用注释设置它们,但它们在单独的内部结构中使用它们似乎并不有用。