【发布时间】:2015-01-12 18:05:06
【问题描述】:
我有两个在项目中使用的类。一类Callback 负责保存来自回调的信息。另一个类UserInfo 是向用户公开的信息。基本上,UserInfo 应该是一个非常薄的包装器,它读取 Callback 数据并将其提供给用户,同时还提供一些额外的东西。
struct Callback {
int i;
float f;
};
struct UserInfo {
int i;
float f;
std::string thekicker;
void print();
UserInfo& operator=(const Callback&);
};
问题是向Callback 添加成员需要在UserInfo 中进行相同的更改,以及更新operator= 和类似的依赖成员函数。为了使它们自动保持同步,我想这样做:
struct Callback {
int i;
float f;
};
struct UserInfo : Callback{
std::string thekicker;
void print();
UserInfo& operator=(const Callback&);
};
现在UserInfo 保证拥有与Callback 相同的所有数据成员。事实上,最重要的是数据成员thekicker。 Callback 中没有声明虚拟析构函数,我相信其他编码人员希望它保持这种状态(他们强烈反对虚拟析构函数的性能损失)。但是,如果UserInfo 类型通过Callback* 销毁,thekicker 将被泄露。应该注意的是,UserInfo 并不打算通过Callback* 接口使用,因此这些类首先是分开的。另一方面,为了修改一个结构而不得不以相同的方式修改三段或更多段代码,感觉不雅且容易出错。
问题:有没有办法允许UserInfo 公开继承Callback(用户必须能够访问所有相同的信息)但不允许分配Callback 引用UserInfo 特别是因为缺少虚拟析构函数?我怀疑这是不可能的,因为它首先是继承的基本目的。我的第二个问题,有没有办法通过其他方法使这两个类保持同步?我想让Callback 成为UserInfo 的成员而不是父类,但我希望使用user.i 而不是user.call.i 直接读取数据成员。
我认为我要求的是不可能的,但我总是对 stackoverflow 答案的巫术感到惊讶,所以我想我只是想看看是否真的有解决这个问题的方法。
【问题讨论】:
-
当关系看起来像一个容器时为什么要继承?
-
也许:让
Callback成为UserInfo的成员并提供转换运算符? -
@KarolyHorvath “我想让
Callback成为UserInfo的成员而不是父类,但我希望使用user.i而不是user.call.i直接读取数据成员。” -
您是否测量虚拟析构函数的性能损失?它会很小。更好的是,当您不使用对象的指针或引用时,编译器可能会完全忽略虚拟查找。
-
@MarkRansom 如果我要使析构函数虚拟化,我必须首先通过测量证明它对性能的影响最小。我毫不怀疑这不会产生影响,但举证责任在我身上。我们正在编译的东西非常复杂,以至于在许多情况下要证明它是一件相当繁琐的事情。