找回密码
 欢迎注册
查看: 7477|回复: 13

[求助] 如何改写构造函数,使之优雅而高效?

[复制链接]
发表于 2019-11-11 14:15:54 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?欢迎注册

×
我有一个 C++ 类 CBiVector,用来处理二维向量相关问题。

下面是简化的代码:
  1. enum class rotate
  2. {
  3.     CW,
  4.     CCW,
  5. };

  6. class CBiVector
  7. {
  8. public:
  9.     explicit CBiVector( const double& x, const double& y ) : m_x{ x }, m_x{ y }{};
  10.     explicit CBiVector( const CBiVector& V ) : CBiVector{ V.m_x, V.m_y }{};
  11.     explicit CBiVector( const CBiVector& V, rotate eRotate ) : CBiVector{ V }
  12.     {
  13.         rotate::CCW == eRotate ? ccw() : cw();
  14.     };

  15.     // ...

  16.     CBiVector& ccw( void )
  17.     {
  18.         const auto t{ m_x };

  19.         m_x = -m_y;
  20.         m_y =  t;

  21.         return *this;
  22.     }

  23.     CBiVector& cw( void )
  24.     {
  25.         const auto t{ m_x };

  26.         m_x =  m_y;
  27.         m_y = -t;

  28.         return *this;
  29.     }

  30.     // ...

  31. private:
  32.     double      m_x;
  33.     double      m_y;
  34. }
复制代码


我现在对第三个构造函数不满意,
它的本意是:构造一个新向量,源于对一个已知向量的顺时针/逆时针90°旋转,
不满意的地方在于,内部有一个 bool 表达式需运行时计算,
可否有消除之道?比如用 模板、constexpr if  之类的技术?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2019-11-11 15:59:24 | 显示全部楼层
竟然悄悄的用到了委托构造,我觉得这个已经可以了,

应该将这个问题 划入 到类的设计模式层面去考虑. 比如考虑另外建立一个 transform 类, 专门负责 向量的各种旋转,平移,剪切 变换,然后向量本身只是作为一种静态的数据实体 entity存在. [好处是逻辑与数据的解耦, 从而保持构造函数的纯粹性,就是只干内存分配这一件事情]
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2019-11-11 16:27:12 | 显示全部楼层
我的初衷是,可以优雅地声明一个只读对象,但希望其中的枚举变量在编译期即可完成使命(以达高效),而非等到运行期才读取和计算:
  1. const CBiVector V{ 0, 1 };

  2. // 可以直接定义一个常量对象
  3. const CBiVector V_ccw{ V, rotate::CCW };

  4. // 而不是如同这样的:
  5. // const CBiVector V_ccw{ CBiVector{ V }.ccw() };
  6. // 或者:
  7. // CBiVector V_ccw{ V };
  8. // V_ccw.ccw(); // 一句话掰成两句,太难看了!
复制代码

点评

这么说吧,我不想写两个非常非常类似的构造函数,一个适用于 ccw(),另一个适用于 cw();况且,若这么做,代码的可读性也比较差  发表于 2019-11-11 17:14
问题是 构造函数本身是在需要在运行时 完成  发表于 2019-11-11 17:03
不过也是在运行时 完成  发表于 2019-11-11 17:02
成员变量-> 临时变量  发表于 2019-11-11 16:55
int tag = 2*bool(rotate::CCW == eRotate)-1; m_x = -tag*m_y; m_y = tag*t;  发表于 2019-11-11 16:55
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2019-11-11 20:44:02 | 显示全部楼层
不能直接上复数吗?
乘正负i很方便的
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2019-11-12 07:28:18 | 显示全部楼层
楼上提到了“复数”,我仔细揣摩了一下,不符合所需。

1、效率方面:旋转功能,我仅需要顺时针/逆时针90°,只需 取反、赋值 操作即可;用复数则还需用到 乘法 操作;

2、功能方面:我需要用到向量的叉乘和点乘,以便快速得到两个向量之间,有向夹角的正余弦;而复数没有对应的叉乘、点乘概念。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2019-11-12 08:04:46 | 显示全部楼层
类似的需求,我希望能显式而高效的定义一个只读对象,它是源自两个向量的 和/差,而后顺/逆时针90°旋转,如何操作?
要求:高效、易读(优雅)
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-11-21 17:47 , Processed in 0.027188 second(s), 18 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表