如何在C ++ Builder中实现Delphi保护的成员访问技巧?

时间:2018-11-21 09:18:26

标签: delphi c++builder c++builder-10.2-tokyo

我需要访问受保护的TControlItem.InternalSetLocation。我德尔福,你会做

type
  THackControlItem = class(TControlItem);

您如何在C ++ Builder中做到这一点?

2 个答案:

答案 0 :(得分:1)

这是一个不错的技巧,我认为Remy Lebeau向我展示了,但现在找不到质量检查了...

//---------------------------------------------------------------------------
#ifndef _TDirectMemoryStream
#define _TDirectMemoryStream
class TDirectMemoryStream:TMemoryStream // just for accessing protected SetPointer
    {
public:
    void SetMemory(BYTE *ptr,DWORD siz) { SetPointer(ptr,siz); Position=0; };
    };
#endif
//---------------------------------------------------------------------------

您只需创建要访问的类的后代的新类。现在只需为受保护的成员添加获取/设置功能...

现在的用法:

TMemoryStream *mem=new TMemoryStream(); // original class instance you want to access

// overtype to our new class and access/use you get/set ...
((TDirectMemoryStream*)(mem))->SetMemory(hdr->lpData,hdr->dwBytesUsed);

delete mem; // release if not needed anymore

我正在使用它来向存储流提供来自vfw相机的自定义内存数据hdr,因此我可以使用TJPEGImage类对其进行正确解码,而不是将数据写入文件并重新加载每帧...

这里是另一个示例:

class A
    {
protected:
    int x;
public:
    int getx(){ return x; }
    };

class hack_A:A
    {
public:
    void setx(int _x){ x=_x; }
    };

void test()
    {
    A a;
    hack_A *ha=(hack_A*)&a;
    ha->setx(10);
    a.getx(); // print the x somwhere
    }

但是,这不适用于私人成员...在这种情况下,它也是可行的,但需要访问A源代码:

class A
    {
protected:
    int x;
private:
    int y;
public:
    int getx(){ return x; }
    int gety(){ return y; }
    friend class hack_A;        // but this one requires access to A soourcecode
    };

class hack_A:A
    {
public:
    void setx(int _x){ x=_x; }
    void sety(int _y){ y=_y; }
    };

void test()
    {
    A a;
    hack_A *ha=(hack_A*)&a;
    ha->setx(10);
    ha->sety(20);
    a.getx(); // print the x somwhere
    a.gety(); // print the x somwhere
    }

答案 1 :(得分:0)

就像在Delphi中一样,您需要继承该类,但还必须重写并公开受保护的函数。但是,我不建议在生产代码中使用它。

class THackControlItem : public TControlItem
{
public:
    void __fastcall InternalSetLocation(int AColumn, int ARow, bool APushed, bool MoveExisting)
    {
        TControlItem::InternalSetLocation(AColumn, ARow, APushed, MoveExisting);
    }
};

在程序中

TControlItem* ci = ...;
static_cast<THackControlItem*>(ci)->InternalSetLocation(...);