介绍性说明:我自愿选择了一个广泛的主题。你知道关于学习捕鱼的报价,就是这样。我不需要回答我的问题,我需要一个解释和建议。我知道你们擅长这个;)
大家好,
我目前正在将一些算法应用到现有程序中。长话短说,我创建了一个新类“Adder”。 Adder 是另一个类的成员,表示实际执行微积分的物理对象,它使用其参数调用adder.calc()(仅用于进行数学运算的对象列表)。
要做这些数学,我需要一些参数,这些参数在类之外不存在(但可以 set ,见下文)。它们既不是配置参数也不是其他类的成员。这些参数是D1和D2,距离以及三个固定大小的数组:alpha,beta,delta。
我知道你们中的一些人阅读代码比阅读文本更舒服,所以在这里:
class Adder
{
public:
Adder();
virtual Adder::~Adder();
void set( float d1, float d2 );
void set( float d1, float d2, int alpha[N_MAX], int beta[N_MAX], int delta[N_MAX] );
// Snipped prototypes
float calc( List& ... );
// ...
inline float get_d1() { return d1_ ;};
inline float get_d2() { return d2_ ;};
private:
float d1_;
float d2_;
int alpha_[N_MAX]; // A #define N_MAX is done elsewhere
int beta_[N_MAX];
int delta_[N_MAX];
};
由于此对象用作另一个类的成员,因此它在* .h:
中声明private:
Adder adder_;
通过这样做,我无法直接在构造函数中初始化数组(alpha / beta / delta)(int T [3] = {1,2,3};),而不必遍历三个数组。我想把它们放在 static const 中,但我不认为这是解决这些问题的正确方法。
我的第二个猜测是使用构造函数初始化数组
Adder::Adder()
{
int alpha[N_MAX] = { 0, -60, -120, 180, 120, 60 };
int beta[N_MAX] = { 0, 0, 0, 0, 0, 0 };
int delta[N_MAX] = { 0, 0, 180, 180, 180, 0 };
set( 2.5, 0, alpha, beta, delta );
}
void Adder::set( float d1, float d2 ) {
if (d1 > 0)
d1_ = d1;
if (d2 > 0)
d2_ = d2;
}
void Adder::set( float d1, float d2, int alpha[N_MAX], int beta[N_MAX], int delta[N_MAX] ) {
set( d1, d2 );
for (int i = 0; i < N_MAX; ++i) {
alpha_[i] = alpha[i];
beta_[i] = beta[i];
delta_[i] = delta[i];
}
}
我的问题是:使用另一个函数 - init() - 会初始化数组会更好吗?或者有更好的方法吗?
我的奖金问题是:您是否看到了一些错误或不良做法?
答案 0 :(得分:5)
你选择了一个非常广泛的主题,所以这是一个更广泛的答案。
我经常看到代码与代码库中的其他地方做同样的事情。确保您的队友或前任尚未解决您尝试解决的问题。
我前一点的延伸。
虽然每个人都应该编写链表或字符串类作为练习,但是没有必要为生产代码编写一个。您可以访问MFC,OWL,STL,Boost等等。如果已经发明了车轮,请使用它并继续编写解决方案以解决真正的问题!
Test Driven Development (TDD)是确保您的代码既可测试又经过测试的一种方式(但不是唯一的方法)。如果您考虑从一开始就测试代码,那么测试将非常容易。 然后测试一下!
The Wikipedia page对此的解释远远超出我的预测。
有意义的标识符只是一个开始。不必要的注释也会降低可读性,因为长函数,具有长参数列表的函数(例如第二个setter)等等。如果您有coding standards,请坚持使用。
const
更多 我对C ++的主要抱怨是默认情况下不是const!在您的示例中,您的getter应声明为const
,并且您的setter应将其参数传递为const
(以及const
- 数组的引用。)
单元测试(如上所述)将确保下一个更改代码的人不会破坏您的实现。
如果您关注Principle of least astonishment并使用单元测试来记录您的库,那么使用它的程序员可以减少问题。
前一点的延伸。尽你所能减少代码重复。今天我目睹了一个必须在十五个不同的地方执行的错误修复(并且只在其中的十三个中执行)。
答案 1 :(得分:4)
创建对象时,我建议始终为用户提供完整的对象,并正确初始化所有成员。 Init方法无法做到这一点,为常见错误腾出空间,无法在两阶段初始化对象中调用初始化函数。
要防止这种情况,请将构造函数设为私有并使用构建器函数或工厂,它们可以访问init方法,或者使init成为私有的,并在构造函数中使用它。最后一条建议通常与在构造函数中进行初始化相同,但它允许多个构造函数使用相同的初始化操作。
答案 2 :(得分:1)
好。 我会:
memset
清除所有值
0(或其他一些值)
构造函数在使用之前。答案 3 :(得分:1)
operator()
。即你打电话给你的是adder_(params)
,而不是adder_.calc(params)
。