你认为多个初始化步骤“形式不好”吗?

时间:2011-01-11 12:30:28

标签: c++ oop

我正在用C ++编写一个物理模拟(Ising模型),它在方格上运行。我的程序的核心是我的Ising类,它带有一个构造函数,用于调用晶格的行和列尺寸。我有另外两种方法来设置系统的其他参数(温度和初始状态),在进化系统之前必须调用因此,例如,示例程序可能看起来像这样

int main() {
    Ising system(30, 30);
    system.set_state(up);
    system.set_temperature(2);

    for(int t = 0; t < 1000; t++) {
        system.step();
    }

    return 0;
}

如果在system.step()之前未调用system.set _ *()方法,则system.step()会抛出异常,提醒用户注意该问题。我用这种方式实现它来简化我的构造函数;这是不好的做法吗?

7 个答案:

答案 0 :(得分:13)

建议尽可能将所有必需参数放在构造函数中(当然有例外,但这些应该很少见 - I have seen one real-world example到目前为止)。通过这种方式,您可以更轻松,更安全地使用课程。

另请注意,通过简化构造函数,您可以使客户端代码更加复杂,哪种IMO是一个不好的权衡。构造函数只编写一次,但调用者代码可能需要写入多次(增加了要编写的代码量和错误的可能性)。

答案 1 :(得分:2)

完全没有,IMO。从外部文件加载数据时我面临同样的问题。创建对象(即,调用它们各自的ctors)时,数据仍然不可用,并且只能在稍后阶段检索。因此,我将初始化分为不同阶段:

  1. 构造
  2. 初始化(第一次激活对象时由框架引擎调用)
  3. 激活(每次激活一个对象时调用)。
  4. 这对我正在开发的框架非常具体,但是没有办法只使用构造函数处理所有内容。

    但是,如果您在调用ctor时知道变量,最好不要使代码复杂化。对于任何使用您代码的人来说,这都是一个令人头疼的问题。

答案 2 :(得分:1)

IMO如果必须每次都调用所有这些初始化步骤,那么这种形式很糟糕。精心设计的软件的目标之一是最大限度地减少搞砸的机会,并且在对象“可用”之前必须调用多个方法只会使得更难以正确使用。如果这些调用是可选的,那么将它们作为单独的方法就可以了。

分享并享受。

答案 3 :(得分:1)

类中的整个点是呈现某种抽象。作为一个类的用户,我应该能够假设它的行为就像它所模拟的抽象一样。

部分原因是类必须始终有效。一旦创建了对象(通过调用构造函数),该类必须处于有意义的有效状态。它应该可以使用了。如果不是,那么它就不再是一个好的抽象。

答案 4 :(得分:0)

如果必须以特定的顺序调用初始化方法,那么我会用自己的方法将调用包装到它们中,因为这表明这些方法本身不是原子的,因此应该如何调用它们的“知识”在一个地方举行。

嗯,这是我的意见,无论如何!

答案 5 :(得分:0)

我想说如果你计划在同一个格子上初始化并运行多个瞬态,那么设置初始条件应该与构造函数分开。

如果运行瞬态并停止,则可以在构造函数中移动设置初始条件,但这意味着您必须传入参数值才能执行此操作。

我完全同意在调用构造函数后对象应该100%准备好使用的想法,但我认为这与设置初始温度场的物理学分开。该对象可以完全可用,但问题中的每个节点都处于绝对零度的相同温度。从传热的角度来看,绝缘体中的均匀温度场并不是很重要。

答案 6 :(得分:0)

正如另一位评论员指出的那样,不得不调用一堆初始化函数。我会在课堂上把它包起来:

class SimulationInfo
{
private:
    int x;
    int y;
    int state;
    int temperature;

public:
    SimulationArgs() : x(30), y (30), state(up), temperature(2) { }; // default ctor
    // custom constructors here!

    // properties
    int x() const { return x; };
    int y() const { return y; };
    int state() const { return state; };
    int temperature() const { return temperature; };
};  // eo class SimulationInfo


class Simulation
{
private:
    Ising m_system;

public:
    Simulation(const SimulationInfo& _info) : m_system(_info.x(), _info.y())
    {
        m_system.set_state(_info.state());
        m_system.set_temperature(_info.temperature());
    } // eo ctor


    void simulate(int _steps)
    {
        for(int step(0); step < _steps; ++steps)
            m_system.step();
    } // eo simulate
}; // eo class Simulation

还有其他方面,但这使得默认设置中的内容更加可用:

SimulationInfo si; // accept all defaults
Simulation sim(si);
sim.simulate(1000);