c++ - 如何从监视列表中隐藏一些类公共(public)属性?

标签 c++ class templates c++builder declspec

我仍在使用 BDS2006(Turbo explorer C++)并且升级仍然不是一个选项。我有一个问题,在调试一些包含以下属性的更高级的模板/类时:

__declspec( property (get=???, put=???) ) ??? ???;
作为成员变量处理 观察名单如果它们太多,调试器就会发疯。结果是大减速在断点和跟踪期间以及偶尔(非常频繁)冷冻 IDE 本身的 当此类类(class)在观察名单中时 (唯一的补救方法是使用 Windows 任务管理器结束 bds.exe 进程树)。
所以我的问题是:
Q1:如何隐藏这些属性,使它们在观察列表中不可见,同时它们仍然存在 public ?
我认为可能有某种宏或指令。使那些不是public不是一种选择。监视列表像处理成员变量而不是函数一样处理此属性。
这里的小例子(从我的 GLSL 数学中提取 vec2 类):
//---------------------------------------------------------------------------
template <class T> class _vec2
    {
public:
    T dat[2];
    _vec2(T _x,T _y) { x=_x; y=_y; }
    _vec2() { for (int i=0;i<2;i++) dat[i]=0; }
    _vec2(const _vec2& a) { *this=a; }
    ~_vec2() {}
    // 1D
    T get_x() { return dat[0]; } void set_x(T q) { dat[0]=q; }
    T get_y() { return dat[1]; } void set_y(T q) { dat[1]=q; }
    __declspec( property (get=get_x, put=set_x) ) T x;
    __declspec( property (get=get_y, put=set_y) ) T y;
    __declspec( property (get=get_x, put=set_x) ) T r;
    __declspec( property (get=get_y, put=set_y) ) T g;
    __declspec( property (get=get_x, put=set_x) ) T s;
    __declspec( property (get=get_y, put=set_y) ) T t;

    // 2D
    _vec2<T> get_xy() { return _vec2<T>(x,y); } void set_xy(_vec2<T> q) { x=q.x; y=q.y; }
    _vec2<T> get_yx() { return _vec2<T>(y,x); } void set_yx(_vec2<T> q) { y=q.x; x=q.y; }
    __declspec( property (get=get_xy, put=set_xy) ) _vec2<T> xy;
    __declspec( property (get=get_xy, put=set_xy) ) _vec2<T> xg;
    __declspec( property (get=get_xy, put=set_xy) ) _vec2<T> xt;
    __declspec( property (get=get_yx, put=set_yx) ) _vec2<T> yx;
    __declspec( property (get=get_yx, put=set_yx) ) _vec2<T> yr;
    __declspec( property (get=get_yx, put=set_yx) ) _vec2<T> ys;
    __declspec( property (get=get_xy, put=set_xy) ) _vec2<T> ry;
    __declspec( property (get=get_xy, put=set_xy) ) _vec2<T> rg;
    __declspec( property (get=get_xy, put=set_xy) ) _vec2<T> rt;
    __declspec( property (get=get_yx, put=set_yx) ) _vec2<T> gx;
    __declspec( property (get=get_yx, put=set_yx) ) _vec2<T> gr;
    __declspec( property (get=get_yx, put=set_yx) ) _vec2<T> gs;
    __declspec( property (get=get_xy, put=set_xy) ) _vec2<T> sy;
    __declspec( property (get=get_xy, put=set_xy) ) _vec2<T> sg;
    __declspec( property (get=get_xy, put=set_xy) ) _vec2<T> st;
    __declspec( property (get=get_yx, put=set_yx) ) _vec2<T> tx;
    __declspec( property (get=get_yx, put=set_yx) ) _vec2<T> tr;
    __declspec( property (get=get_yx, put=set_yx) ) _vec2<T> ts;

    // operators
    _vec2* operator = (const _vec2 &a) { for (int i=0;i<2;i++) dat[i]=a.dat[i]; return this; }                              // =a
    T& operator [](const int i)     { return dat[i]; }                                                                      // a[i]
    _vec2<T> operator + ()          { return *this; }                                                                       // +a
    _vec2<T> operator - ()          { _vec2<T> q;       for (int i=0;i<2;i++) q.dat[i]=      -dat[i];           return q; } // -a
    _vec2<T> operator ++ ()         {                   for (int i=0;i<2;i++)                 dat[i]++;     return *this; } // ++a
    _vec2<T> operator -- ()         {                   for (int i=0;i<2;i++)                 dat[i]--;     return *this; } // --a
    _vec2<T> operator ++ (int)      { _vec2<T> q=*this; for (int i=0;i<2;i++)                 dat[i]++;         return q; } // a++
    _vec2<T> operator -- (int)      { _vec2<T> q=*this; for (int i=0;i<2;i++)                 dat[i]--;         return q; } // a--

    _vec2<T> operator + (_vec2<T>&v){ _vec2<T> q;       for (int i=0;i<2;i++) q.dat[i]=       dat[i]+v.dat[i];  return q; } // a+b
    _vec2<T> operator - (_vec2<T>&v){ _vec2<T> q;       for (int i=0;i<2;i++) q.dat[i]=       dat[i]-v.dat[i];  return q; } // a-b
    _vec2<T> operator * (_vec2<T>&v){ _vec2<T> q;       for (int i=0;i<2;i++) q.dat[i]=       dat[i]*v.dat[i];  return q; } // a*b
    _vec2<T> operator / (_vec2<T>&v){ _vec2<T> q;       for (int i=0;i<2;i++) q.dat[i]=divide(dat[i],v.dat[i]); return q; } // a/b

    _vec2<T> operator + (const T &c){ _vec2<T> q;       for (int i=0;i<2;i++) q.dat[i]=dat[i]+c;                return q; } // a+c
    _vec2<T> operator - (const T &c){ _vec2<T> q;       for (int i=0;i<2;i++) q.dat[i]=dat[i]-c;                return q; } // a-c
    _vec2<T> operator * (const T &c){ _vec2<T> q;       for (int i=0;i<2;i++) q.dat[i]=dat[i]*c;                return q; } // a*c
    _vec2<T> operator / (const T &c){ _vec2<T> q;       for (int i=0;i<2;i++) q.dat[i]=divide(dat[i],c);        return q; } // a/c

    _vec2<T> operator +=(_vec2<T>&v){ this[0]=this[0]+v; return *this; };
    _vec2<T> operator -=(_vec2<T>&v){ this[0]=this[0]-v; return *this; };
    _vec2<T> operator *=(_vec2<T>&v){ this[0]=this[0]*v; return *this; };
    _vec2<T> operator /=(_vec2<T>&v){ this[0]=this[0]/v; return *this; };

    _vec2<T> operator +=(const T &c){ this[0]=this[0]+c; return *this; };
    _vec2<T> operator -=(const T &c){ this[0]=this[0]-c; return *this; };
    _vec2<T> operator *=(const T &c){ this[0]=this[0]*c; return *this; };
    _vec2<T> operator /=(const T &c){ this[0]=this[0]/c; return *this; };
    // members
    int length() { return 2; }  // dimensions
    };
//---------------------------------------------------------------------------
template <class T> T min(const T &a,const T &b)  { if (a<b) return a; return b; }
template <class T> T max(const T &a,const T &b)  { if (a>b) return a; return b; }
double abs(const double &a) { if (a<0.0) return -a; return a; }
//---------------------------------------------------------------------------
// get vector size
template <class T> double   length   (const _vec2<T> &v)  { double l=0.0; for (int i=0;i<2;i++) l+=v.dat[i]*v.dat[i]; return sqrt(l); }
// get vector size^2
template <class T> double   length2  (const _vec2<T> &v)  { double l=0.0; for (int i=0;i<2;i++) l+=v.dat[i]*v.dat[i]; return l; }
// get unit vector
template <class T> _vec2<T> normalize(const _vec2<T> &v)  { _vec2<T> q=v; double l=divide(1.0,length(v)); for (int i=0;i<2;i++) q.dat[i]*=l; return q; }
// get dot product
template <class T>       T  dot  (const _vec2<T> &v1,const _vec2<T> &v2) { T l=0.0; for (int i=0;i<2;i++) l+=v1.dat[i]*v2.dat[i]; return l; }
// c+v
template <class T> _vec2<T> operator + (double c,_vec2<T>&v){ _vec2<T> q; for (int i=0;i<2;i++) q.dat[i]=c+v.dat[i];  return q; }
// c-v
template <class T> _vec2<T> operator - (double c,_vec2<T>&v){ _vec2<T> q; for (int i=0;i<2;i++) q.dat[i]=c-v.dat[i];  return q; }
// c*v
template <class T> _vec2<T> operator * (double c,_vec2<T>&v){ _vec2<T> q; for (int i=0;i<2;i++) q.dat[i]=c*v.dat[i];  return q; }
//---------------------------------------------------------------------------
typedef _vec2<float >  vec2;
typedef _vec2<double> dvec2;
typedef _vec2<bool  > bvec2;
typedef _vec2<int   > ivec2;
typedef _vec2<DWORD > uvec2;
//---------------------------------------------------------------------------
vec2 GLSL_math_test2;   // ensure that template code is compiled/linked
//---------------------------------------------------------------------------
用法:
vec2 a;
a=vec2(0.1,0.2);
a+=a;         // <<- here breakpoint
观察名单:
[+]a    { { 0.1, 0.2 }, ????, ????, ????, ????, ????, ????, ????, ????, ????, ????, ????, ????, ????, ????, ... }
如果我打开 [+] a的子菜单看它显示:
[-]a    { { 0.1, 0.2 }, ????, ????, ????, ????, ????, ????, ????, ????, ????, ????, ????, ????, ????, ????, ... }
  [+]dat {0.1,0.2}
所以没有更多的属性......这可能暗示监视列表窗口可能以某种方式配置以通过一些隐藏选项来实现这一点。
这个小的单类实例不是一个大问题,但是当我改为这样的时候:
vec2 a[20];
a[0]=vec2(0.1,0.2);
a[1]=a[0]; // <<- here breakpoint
并观看a IDE 再次在断点处立即卡住,只有 Kill 进程是我的下一个可能步骤。现在想象更大的项目,其中有更多的类和动态列表......这样的项目不再可能正确(或根本)调试。
PS。 BDS2006 中IDE 的卡住是一个众所周知的错误。如果监视列表显示太多数据(它可能只是一个长字符串,没什么花哨的),IDE 会减慢并卡住(根据显示的数据量和 F7/F8 执行的步骤数)。
编辑1:
作为一种解决方法,我添加了配置宏来禁用不需要它的应用程序的大部分调配。这是一个简单类的监视列表屏幕截图示例:
Watch list
但是有很多东西需要调配,甚至像这样简单的东西已经超出了观察窗口的极限。
Edit2:进度更新
没有#pragma声明看起来很有希望。从 2010 年开始 Debugger_Visualizers已添加到可以解决此问题的 IDE 中,但是我仍在使用旧版本,并且目前无法选择移植。
数组的当前解决方法:
vec2 a[20];
a[0]=vec2(0.1,0.2);
a[1]=a[0]; // <<- here breakpoint
watch :
| a[0].dat,20 | { 0.1, 0.2 }, { 0.1, 0.2 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } |
所以对于单个实例使用 vec2::dat成员而不是 vec2 .对于使用数组监视格式的数组 a[start index].dat,number of items而不是 a .
这很快(不会卡住),但是由于硬编码的大小(必须是硬编码的数字,没有表达式或变量),它可能会违反访问权限。这仍然不能用于整个struct/classes更复杂(如多边形、网格),但至少现在有一些用于数组的调试选项。

最佳答案

当您想改变对象在调试环境中的可视化方式时,您可以尝试使用 native visualisers .我愿意给你一些信息,但是看到这个主题的大小,也许你在决定是否使用这项技术之前首先想先看看。

关于c++ - 如何从监视列表中隐藏一些类公共(public)属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62712772/

相关文章:

c++ - 从基类型的函数返回派生类对象

ios遗传与 objective-c ,如何调用方法而不是重复它

python - 如何从 django templatetag 访问 python 列表?

c++ - C++17 中的新功能 : template templates that match by default

c++ - 如何检查一个 float 是否是 C++ 中的真实数字?

c++ - 将派生类作为虚拟基类传递而不丢失更改

c++ - cpp从需要父类(super class)对象的函数访问子类对象方法

c++ - 从终端在 Linux 机器上用 C++ 创建并包含头文件

c++ - 结构模板的默认参数

c++ - OpenCV 只对鱼眼图像的中心部分进行不失真处理