java C++类的C++等价性 我正在研究一些java代码到C++的翻译。

java C++类的C++等价性 我正在研究一些java代码到C++的翻译。,c++,anonymous-class,C++,Anonymous Class,在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++中,我知道我可以创建如下的匿名

在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++不允许匿名类中的构造函数,它不允许从对象扩展,例如新的x5{公共工作{}},就像java允许的那样。

如何在C++中编写类似的代码?< /P> 更新日期:2020年3月7日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);

C++具有匿名名称空间,可有效地让您创建与声明它们的转换单元完全隔离的类:

namespace {

   class X {

   public:
          X(int) { /* ... */ }     // Ok to have a constructor

          void work();
    };

}

int main(int argc, char **argv)
{
    X entity{5};

    // ...
}
现在,您必须在全局范围内声明它们,而不能在内部范围内声明它们。您还需要为这些类提供普通名称,以便在同一翻译单元中引用它们;但实际上,它们是完全匿名的,其他翻译单位无法访问。另一个翻译单元可以声明自己的匿名类X,并且不会有任何冲突

您可以以所有其他正常方式使用匿名类,对它们进行子类化,等等。。。您可以创建一个匿名类,它是一个常规的、非匿名类的子类,这使您非常接近Java的功能


有些编译器还提供扩展,您可以在内部作用域中声明类,它们的工作方式也非常类似于匿名名称空间,但这将是特定于编译器的扩展。

C++具有匿名名称空间,这样可以有效地创建与声明它们的转换单元完全隔离的类:

namespace {

   class X {

   public:
          X(int) { /* ... */ }     // Ok to have a constructor

          void work();
    };

}

int main(int argc, char **argv)
{
    X entity{5};

    // ...
}
现在,您必须在全局范围内声明它们,而不能在内部范围内声明它们。您还需要为这些类提供普通名称,以便在同一翻译单元中引用它们;但实际上,它们是完全匿名的,其他翻译单位无法访问。另一个翻译单元可以声明自己的匿名类X,并且不会有任何冲突

您可以以所有其他正常方式使用匿名类,对它们进行子类化,等等。。。您可以创建一个匿名类,它是一个常规的、非匿名类的子类,这使您非常接近Java的功能


<>一些编译器还提供了扩展,在内部范围内可以声明类,它们也会与匿名命名空间非常相似,但这将是编译器特定的扩展。

< P>我不能说我知道如何编写习惯性java,但我猜想java中的这种模式是C++中lambDas的替代。我记得很久以前在使用Swing时使用了一个匿名类。我想我是这样做的:

button.addMouseListener(new MouseAdapter() {
  public void mouseClicked(MouseEvent e) {
    // ...
  }
});
这是从类继承和重写方法的关键。确切地说,这不是我想在C++中附加事件侦听器的方式。我更愿意这样做:

button.addMouseClickListener([](const MouseEvent &e) {
  // ...
});
对于事件侦听器,闭包需要存储在std::函数或类似的东西中。这与虚拟调用的性能大致相同

我真的不知道在哪里使用这个类,但是如果你需要像事件监听器一样将它存储在一边,那么长时间声明这个类或者使用std::function可能是最干净的选择。如果您不需要像算法策略那样将其存储在一边,那么您可以使用函子。当然,你可以把一个函子放在一边,但是它需要一些模板机制,可能不值得,尽管它有更多的灵活性

struct MyPolicy {
  int doSomething(int i) {
    return i * 3;
  }

  double getSomething() const {
    return d;
  }

  double d;
};

template <typename Policy>
void algorithm(Policy policy) {
  // use policy.doSomething and policy.getSomething...
}

<> P>诚实地说,我认为最好的解决方案是不要尝试在C++中实现java特性。我的意思是,如果您需要在某个特定操作中处理多个列,那么只需为此创建一个类。不要走捷径。即使你只在一个地方使用它,也可以给它起个名字。

我不能说我知道如何编写习惯性java,但是我猜想java中的这种模式是C++中lambdas的替代。我记得很久以前在使用Swing时使用了一个匿名类。我想我是这样做的:

button.addMouseListener(new MouseAdapter() {
  public void mouseClicked(MouseEvent e) {
    // ...
  }
});
这是从类继承和重写方法的关键。确切地说,这不是我想在C++中附加事件侦听器的方式。我更愿意这样做:

button.addMouseClickListener([](const MouseEvent &e) {
  // ...
});
对于事件侦听器,闭包 uld需要存储在std::函数或类似的东西中。这与虚拟调用的性能大致相同

我真的不知道在哪里使用这个类,但是如果你需要像事件监听器一样将它存储在一边,那么长时间声明这个类或者使用std::function可能是最干净的选择。如果您不需要像算法策略那样将其存储在一边,那么您可以使用函子。当然,你可以把一个函子放在一边,但是它需要一些模板机制,可能不值得,尽管它有更多的灵活性

struct MyPolicy {
  int doSomething(int i) {
    return i * 3;
  }

  double getSomething() const {
    return d;
  }

  double d;
};

template <typename Policy>
void algorithm(Policy policy) {
  // use policy.doSomething and policy.getSomething...
}

<> P>诚实地说,我认为最好的解决方案是不要尝试在C++中实现java特性。我的意思是,如果您需要在某个特定操作中处理多个列,那么只需为此创建一个类。不要走捷径。给它起一个名字,即使你可能只在一个地方使用它。

你必须给这个类起一个名字。我想你可以用一个函数指针来达到类似的效果,需要一个全新的类型。如果无法更改X或需要通过类X添加到类型{std::function work=[]{/***/};},则这不是正确的方法;intmain{xfoo{[]{/***/}};}。你最好专注于你想要完成的事情。C++有java的C++工具,使用C++的最佳工具可以比在C++中复制java工具更好。你必须给类命名。我猜你可以用一个函数描述的函数指针来获得一个类似的效果,需要一个全新的类型。如果无法更改X或需要通过类X添加到类型{std::function work=[]{/***/};},则这不是正确的方法;intmain{xfoo{[]{/***/}};}。你最好专注于你想要完成的事情。C++有不同的工具,Java使用的C++工具最好能比C++中的java java工具更好的工作。谢谢你的回答和建议。我所写的实际上是一个包含多个方法的聚合,因此单个函数指针不起作用。我已经更新了我的问题,以便更准确地描述上下文。我喜欢为自定义操作创建一个单独的子类,并带有一个函数。感谢您的回答和建议。我所写的实际上是一个包含多个方法的聚合,因此单个函数指针不起作用。我已经更新了我的问题,以便更准确地了解上下文。我喜欢为自定义的操作创建一个单独的子类,并使用一个函数。