我的问题是关于编码风格和C ++中复杂表达式的分解。
我的程序有一个复杂的类层次结构,由类等组成的类组成。许多程序的对象都持有指向其他对象的指针或索引。有一些名称空间。正如我所说,它很复杂 - 我的意思是它是一个非常典型的10,000行C ++程序。
出现了规模问题。我的代码开始有许多不可读的表达式,如p->a(b.c(r).d()).q(s)->f(g(h.i()))
。 (正如我所说,这是不可读的。我无法阅读它,我就是那个写它的人!你可以只看它来捕捉心情。)我试过重写这样的表达式
{
const I ii = h.i();
const G &gg = g(ii);
const C &cc = b.c(r);
// ..
T *const qq = aa.q(s);
qq->f(gg);
}
所有那些本地范围的符号可以说代码更具可读性,但我承认我并不关心整体风格。毕竟,一些本地符号是const &
引用,而其他符号代表数据的副本。如果我不小心省略了&
之一,从而调用了某个大对象的不必要副本,该怎么办?我的编译器几乎不会警告我。
此外,带有本地符号的版本是详细的。
两种解决方案都不适合。在C ++中是否存在更难惯用的,不易出错的方法来分解不可读的表达式?
例证
如果问题的最小,可编辑的说明有帮助,那么这里就是一个。
#include <iostream>
class A {
private:
int m1;
int n1;
public:
int m() const { return m1; }
int n() const { return n1; }
A(const int m0, const int n0) : m1(m0), n1(n0) {}
};
class B {
private:
A a1;
public:
const A &a() const { return a1; }
B(const A &a0) : a1(a0) {}
};
B f(int k) {
return B(A(k, -k));
}
int main() {
const B &my_b = f(15);
{
// Here is a local scope in which to decompose an expression
// like my_b.a().m() via intermediate symbols.
const A &aa = my_b.a();
const int mm = aa.m();
const int nn = aa.n();
std::cout << "m == " << mm << ", n == " << nn << "\n";
}
return 0;
}
其他信息
我怀疑它与问题有关,但如果是:我的程序定义了几个模板,但目前不使用任何运行时多态。
实际示例
其中一位评论者请求我的代码中的实际示例。这是:
bool Lgl::is_order_legal_for_movement(
const Mb::Mapboard &mb, const size_t ix, Chains *const p_chns1
) {
if (!mb.accepts_orders()) return false;
const Basic_mapboard &bmb = mb.basic();
if (!is_location_valid(bmb, ix, false)) return false;
const Space &x = mb.spc(ix);
if (!x.p_unit()) return true;
const size_t cx = x.i_cst_occu();
const Basic_space &bx = x.basic();
const Unit &u = x.unit();
const bool army = u.is_army();
const bool fleet = u.is_fleet();
const Order order = u.order();
const size_t is = u.source();
const Location lt = u.target_loc();
const size_t it = lt.i_spc;
const size_t ct = lt.i_cst;
// ...
{
const Space &s = mb.spc(is);
const Basic_space &bs = s.basic();
result = (
(army_s && (
bs.nbor_land(it) || count_chains_if(
Does_chain_include(ix), chns_s, false
)
)) || (fleet_s && (
// By rule, support for a fleet can name a coast,
// but need not.
ct == NO_CST
? is_nbor_sea_no_cst(bs, cs, it)
: is_nbor_sea (bs, cs, lt)
))
) && is_nbor_no_cst(army, fleet, bx, cx, it);
}
// ...
}
答案 0 :(得分:1)
对于您的实际代码示例,我可以看到您为什么要使其更具可读性。我可能会重新编码:
if (army_s) {
result = bs.nbor_land(it) ||
count_chains_if(Does_chain_include(ix), chns_s, false);
} else if (fleet_s) {
// By rule, support for a fleet can name a coast,
// but need not.
if (ct == NO_CST)
result = is_nbor_sea_no_cst(bs, cs, it);
else
result = is_nbor_sea(bs, cs, lt);
}
result &= is_nbor_no_cst(army, fleet, bx, cx, it);
它执行相同的逻辑,包括短路评估,但我认为对人类解释有点好。我还遇到过编译器,这些编译器也使用这种样式生成更好的代码,而不是原始代码包含的非常复杂的复合行。
希望有所帮助。