【发布时间】:2020-03-07 01:40:51
【问题描述】:
我正在将一些 Java 代码翻译成 C++。
在 Java 中,我们可以从匿名类创建对象,使用现有的构造函数,并覆盖一些方法。例如,
class X {
public X(int value) {...}
public void work() {....}
}
void main(String[] args) {
X entity = new X(5) {
public void work() { /* Something else */ }
};
}
在 C++ 中,我知道我可以创建如下匿名类:
class X {
public:
virtual void work() {...}
}
class : public X {
public:
void work() {....}
} obj;
但是 C++ 不允许匿名类中的构造函数,并且它不允许从对象扩展(例如,new X(5) { public void work() {} } 就像 Java 允许的那样。
如何在 C++ 中编写类似的代码?
更新 03/07/2020 05:27 CDT
关于我正在处理的问题的更多背景信息。我正在实现内存中 SQL 数据库的聚合功能,并使用以下类来表示聚合字段:
class AggField {
public:
AggField(int colIndex);
virtual void reduce(DataRow&) = 0;
virtual double output() = 0;
}
对于每种类型的聚合,例如 avg、min/max 和 sum,我都有一个子类。例如
class Avg : public AggField {
private:
int counter_;
double value_;
public:
Avg(int colIndex) : AggField(colIndex), counter_(0), value_(0) {};
void reduce(DataRow&) override {
value_ += row[colIndex].doubleval();
counter_ += 1;
}
double output() override {
return value_ / counter_;
}
}
class Sum : public AggField {
.....
}
在处理一张表的时候,我会写如下
Table table = ...
auto agg_opr = Agg({
new Sum(0),
new Avg(1)
});
agg_opr.agg(table);
在第 0 列求和,在第 1 列求平均值。
有时(很少)我需要处理多个输入列。例如,对 col1 * (1 + col2) 求和。我不想创建一个新的 AggField 子类,而是写一些类似的东西:
Table table = ...
auto agg_opr = Agg({
new Sum(0) {
void reduce(DataRow& row) {
value_ += row[0].doubleval() * (1 + row[1].doubleval());
}
},
new Avg(1),
new Max(1)
});
agg_opr.agg(table);
【问题讨论】:
-
你必须给这个类起个名字。
-
我想你可以使用一些描述的函数指针来获得类似的效果,需要一个全新的类型。 (如果您无法更改
X或需要添加到类型,则不是正确的方法)class X { std::function<void()> work = [] () { /***/ }; }; int main() { X foo { [] () { /***/ } }; }。 -
你最好专注于你想要完成的事情。 C++ 的工具与 Java 不同,使用最好的 C++ 工具来完成这项工作可能比尝试在 C++ 中复制 Java 的工具效果更好。
标签: c++ anonymous-class