C++ RAM高效C++;财产

C++ RAM高效C++;财产,c++,properties,C++,Properties,属性是类的公共数据成员,可由客户端代码访问。当客户机代码读取或修改属性时,所属对象将接收一个通知(以get/set通知回调的形式) 有些语言(如C#)具有内置属性 我想为C++创建一个将是RAM有效的属性。 创建属性最明显的方法如下所示: class超级; 结构属性{ Prop(Super*Super):超级超级超级(*Super),超级超级超级(0){} int运算符=(int a); 运算符int()常量; 国际货币基金组织; Super&m_Super; }; 超级结构{ Super():

属性是类的公共数据成员,可由客户端代码访问。当客户机代码读取或修改属性时,所属对象将接收一个通知(以get/set通知回调的形式)

有些语言(如C#)具有内置属性

我想为C++创建一个将是RAM有效的属性。 创建属性最明显的方法如下所示:

class超级;
结构属性{
Prop(Super*Super):超级超级超级(*Super),超级超级超级(0){}
int运算符=(int a);
运算符int()常量;
国际货币基金组织;
Super&m_Super;
};
超级结构{
Super():一(这个),二(这个){}
void start(){printf(“set”);}
void onGet(){printf(“get”);}
一号提案;
第二号提案;
};
int Prop::operator=(int a){m_super.start();m_a=a;返回a;}
运算符int()常量{m_super.onGet();返回m_a;}

问题是每一个属性都必须保持指向一个我认为昂贵的外部类的指针。< /P> 我想知道是否有一种更有效的方法来实现这一点? 例如,如果生成了所有的

Super
-类,标准是否允许从属性的
指针获取指向外部类的指针

大概是这样的:

struct Prop{
属性(uint8_t offset):m_offset(offset),m_a(0){}
int运算符=(int a);
运算符int()常量;
国际货币基金组织;
常数8μt mμ偏移量;
};
int Prop::运算符=(INTA){
Super*Super=(Super*)((char*)this)+m_偏移量;
super->start();m_a=a;返回a;
}
超级结构{
//假设性质的精确顺序
Super():一(0),两(sizeof(Prop)){}
void start(){printf(“set”);}
void onGet(){printf(“get”);}
一号提案;
第二号提案;
};
因为这个偏移量是一个常量表达式,所以(理论上)可以保存在ROM中(或者至少可以小于sizeof(指针))


或者有其他方法吗?

我显然不知道代码的上下文,因此在您的特定实现中这可能是不可想象的,但您可以这样做

class Prop(){
  Prop() : m_a(0){};
  int operator=(int a){m_a = a;};
  int m_a;
}

class Super(){
public:
  int set_prop(int index, int value){
    m_props[index] = value;
    onSet();
    return value;
  }
private:
  void onSet(){};
  std::vector<Prop> m_props;
}
class-Prop(){
Prop():m_a(0){};
int运算符=(int a){m_a=a;};
国际货币基金组织;
}
超级类(){
公众:
int set_prop(int索引,int值){
m_props[索引]=值;
起病();
返回值;
}
私人:
空起始(){};
std::向量m_道具;
}
显然,您需要初始化向量并处理错误情况等,但逻辑是存在的-如果您仅通过
super
访问
prop
s

这就只剩下了结构序列的大小,没有返回到
super

的指针,c++的属性是语言扩展 不要再看了,
msvc

clang
编译器也支持此语法。我对gcc不太清楚

存储偏移量也可以这样做 只需在构造函数中计算此
的偏移量,ala:

Prop( Super& super ) {
  uint8_t offset = this - std::addressof(super );//somewhat unmaintable - but may save some bytes
}
然后使用时,使用


请注意,由于对齐和填充,节省的空间可能比看起来要少。

获取或设置操作不需要(或使用)Super。@stark eehmm。。怎样?如果我需要在get/set操作中调用Super的非静态方法,那么如果没有指向Super对象的指针,我怎么做呢?出于好奇,展示一个使用您的提议的
Super
,不管怎样,标准不支持以您提议的方式从其组合成员中寻址对象,除了第一个成员,谁的地址保证是构成外部对象的地址。(例如,零偏移量成员)。@WhozCraig抱歉,你能澄清一下你想让我展示什么吗?@WhozCraig'标准不支持从其组成的成员中寻址对象',这很遗憾。您知道这方面的具体条款吗?您建议按索引访问属性?这有点超出了一个属性的全部意义——它应该看起来像一个普通的价值成员。我看到你在原来的问题上添加了一些额外的描述,如果你愿意的话,这确实使我的解决方案有点“误导”。我理解这个问题只是关于在超类中存储任何类型的数据,并引用超类。不幸的是,我不能使用语言扩展。从一个ctor计算一个偏移量是一个好主意,谢谢:)显然它需要额外的检查来确保偏移量适合uint8。谢谢你更新这个。差分计算的逆转使这一点可行。不可取,但仍然可行。此外,这将与非Prop成员混合使用。坦率地说,节省的空间是名义上的(在典型的填充中,OP将节省一个巨大的字节,至少在大多数x86实现中是如此,在x64上是五个字节)@WhozCraig关于对齐的观点很好-我添加了一条关于对齐的注释that@WhozCraig我认为使用
packed
attribute可以节省更多的钱-虽然它也是一个语言扩展,但它的支持范围更广(或者我应该说“我的编译器支持它”:)。他们是声明成员。除非你试图压缩代码以适应256KB的RLL编码器或其他一些过时的实体坦率地说,我看不到回报,但我不必这样做;你知道,这才是真正重要的。这个答案是可靠的,顺便说一句,如果不是直接选择的话,至少值得一提。