【问题标题】:Abstract Class Initialization in C++C++ 中的抽象类初始化
【发布时间】:2015-07-19 21:51:48
【问题描述】:

在 Java 中,您可以初始化一个抽象类,而无需通过实现抽象方法来派生一个派生类。例如:

public abstract class A { public abstract void a(); }
public class Test {
    public static void main(String[] args) {
        A b = new A() { @Override public void a() { System.out.println("Test"); } }
    }
}

我的问题是:你能在 C++ 中做类似的事情吗?

【问题讨论】:

  • 副本比这个简单的问题复杂大约 10 倍。更简洁的答案是:“不。但请阅读更多关于 C++11 lambda 的内容。”
  • C++ 中不需要它。在 Java 中,匿名类用于实现 lambdas(在 Java8 之前,lambdas 被引入到语言中)。在 C++ 中,可以直接使用 lambda,无需实现抽象类。
  • @ChristianHackl 我同意,这就是我投票重新提出这个问题的原因。

标签: c++


【解决方案1】:

C++ 不支持这个。

但是 C++ 通常使用较少的 OOP(在“使用虚函数”的意义上使用“OOP”)。特别是,从 C++11 开始,lambdas 为 Java 中许多基于 OOP 的模式提供了强大的替代方案。

这是一个非常简单的例子:

#include <functional>
#include <iostream>

void f(std::function<void()> a)
{
    a();
}

int main()
{
    f([]() { std::cout << "Test\n"; });
}

或者:

#include <iostream>

template <class Operation>
void f(Operation operation)
{
    operation();
}

int main()
{
    f([]() { std::cout << "Test\n"; });
}

事实上,现在 lambda 在编程中变得如此流行,以至于 Java 8 也支持它们:

https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html

【讨论】:

  • @Codorilla:C++中最常用的OOP定义涉及到虚函数的使用。请参阅 Bjarne 本人在 stroustrup.com/bs_faq.html#oop 使用的定义。 Lambda 与虚函数没有任何关系。而关于 lambdas 的新特性正是 OP 试图模仿的 Java 特性的定义点:它们是匿名的
【解决方案2】:

Java 不允许在没有派生非抽象类的情况下实例化抽象类。它只允许您直接在实例化点派生“内联”类,这被称为匿名类

您可以在 C++ 中实现类似的效果。

#include <iostream>

struct ABC
{
  virtual void f() = 0;
  virtual ~ABC() {}
};

int
main()
{
  struct : ABC { void f() override { std::cout << "okay\n"; } } anon {};
  anon.f();
}

【讨论】:

  • 我会说这是一个类似的效果。您必须为实例命名。
  • @ChristianHackl 我正在命名 instance,而不是 type。除非我遗漏了什么,否则这与 OP 在 Java 示例中所做的相同。但是,我不确定如何在免费商店中创建对象。
  • 在 Java 中,您也不必为实例命名。
  • 或者更确切地说,您不必命名它。 OP 对实例的命名以某种方式违背了 Java 中模式的目的。您通常会将A 的实例传递给someOtherMethod(new A() { @Override public void a() { System.out.println("Test"); } }); 等方法。
  • @ChristianHackl 很公平,我采用了你的措辞。
【解决方案3】:

答案是否定的。 您所说的 Java 功能称为“匿名类”,而这种功能在 C++ 中根本不存在。

【讨论】:

  • 你认为@5gon12eder 的解决方案是什么?
  • 他仍然必须以某个名称调用他的实例,因此它并不是 Java 匿名类的真正替代品
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-01
  • 1970-01-01
  • 2016-05-21
  • 2021-11-27
  • 2014-10-13
  • 2013-12-30
  • 1970-01-01
相关资源
最近更新 更多