当前位置: 首页 > 面试题库 >

java.lang.Object x = new Foo()的C ++等效项是什么?

关学
2023-03-14
问题内容

C ++等于java.lang.Object x = new Foo()什么?


问题答案:

在C 中没有与此等效的方法,尝试在C

中进行Java编程毫无意义。话虽如此,我将从尝试尽可能模仿陈述的赋值特征和精神的角度来探讨这一问题。我建议的每种方式都有缺点和局限性。前两个不是真正的惯用C
++,但是了解它们很重要,以了解后两个解决了哪些问题。

1. C样式的void指针。

让我从最基本,最有用的空指针开始:

void* foo = new Foo();

可以从new运算符将任何东西分配给void指针,因为new,placement
new等总是返回void指针。缺点应该是显而易见的:丢失有关所指向对象的类型信息。首先,C
++缺少反射或任何查询对象的方法。您必须将类型信息放在脑海中,并使用来回转换来实际使用它。由于没有任何类型安全的方法可以从void指针进行强制转换,因此可能会引起欢喜。

如果这是函数的返回类型:

void* foo = some_function( _arg0 );

使用您的代码的任何作者都需要弄清楚 应该 怎么做。不幸的是,通常情况下它们应该发生什么,而您(作者)认为应该从函数返回的结果却大不相同。

2. C型联合

如果你想自己限制其支持的,而不是无限类型java.lang.Object中可以处理则有N种类型的工会。
只要它们是POD数据类型,它们就可以
在同一存储空间上保存一组预定义的值类型。工会缺乏两个非常重要的事情:知道分配哪个值的能力和持有非POD类型的能力。这将它们完全排除在具有任何功能(例如)的任何对象中std::string

为了澄清以上内容的实际含义:

union myType{
    int a;
    char b[4];
};

如果我在“ myType”的实例的“ b”部分中设置了第一个字符,那么我还将int的第一个字节设置为相同的值。在C
中,它们实际上仅对内存黑客和极低级别的编程(例如嵌入式等)有用。它们不是惯用的C

3. Boost :: Any

现在,如果您真正想要“我可以拿任何东西”,请使用Boost ::
Any。这可以容纳任何对象而不会破坏很多有用的类型信息。Boost文件的目的比我要好。取自Any的简介部分:

有时需要泛型(从一般意义上来说,与基于模板的编程相反):真正可变的变量,可容纳许多其他更特定类型的值,而不是C ++的常规严格和静态类型。

可以考虑解决与空指针相关的许多问题,例如丢失有关所包含对象的信息以及安全地转换为正确类型的能力。

4. Boost :: Variant

Boost ::
Variant解决了与union相同类型的问题,而不会丢失对象信息。此外,它可以与非POD类型的对象一起使用。如文档所述,最好:

典型的解决方案以动态分配对象为特征,这些对象随后通过一个通用的基本类型(通常是虚拟基本类Hen01或更危险的是void
*)进行操作。然后可以通过多态下垂构造(例如dynamic_cast,boost :: any_cast等)来检索具体类型的对象。

但是,由于以下原因,此类解决方案极易出错:

  1. 在编译时无法检测到向下转换错误。因此,不正确使用向下构造会导致仅在运行时才能检测到错误。
    2.
    新的混凝土类型的添加可以忽略。如果将新的具体类型添加到层次结构中,则现有的向下转换代码将继续按原样工作,而完全忽略了新类型。因此,程序员必须在多个位置手动定位和修改代码,这通常会导致难以找到运行时错误。

编辑:

重新整理以显示我回答OP时的想法和原因。我也在下面谈到了评论。



 类似资料:
  • 问题内容: 我有以下代码,该代码将字符串作为输入,并转换为UNIX时间戳。我想在golang中做同样的事情,但我无法识别将在Go中提供等效于DateTimeOffset结构的结构或函数。 例如: 输入:635804753769100000 输出:1444878577 UTC对应时间:10/15/2015 3:09:36 AM +00:00 有人可以帮我解决这个问题,以获得上述结果。 谢谢 问题答案

  • 问题内容: Golang中C ++的等效功能是什么? 根据这里的问题,我可以得到以下声明: 但这将导入整个名称空间。现在我只想使用诸如定义之类的东西 Go中有与此等效的功能,因此我不必一直输入吗? 问题答案: 以下代码在可读性方面接近,但效率较低,因为编译器无法再内联函数调用。 而且,它具有输入名称的副作用,并到该文件的范围,这恐怕是C ++的没有做。

  • 问题内容: MSDN中AutoResetEvent的描述 我正在尝试将在C#中实现的线程池移植到Linux下的C ++。我不知道应该使用哪些行为与“ AutoResetEvent”类似的函数。 问题答案: AutoResetEvent最类似于二进制信号量。人们说“条件变量”本身并没有错,但是条件变量用于类似的情况,而不是类似的对象。您可以在条件变量之上实现一个(未命名的)AutoResetEven

  • 问题内容: 将Java转换为C#时,将语言环境转换为CultureInfo的正确方法是什么? 我知道在C#中,我们拥有当前线程的文化,并且在某些情况下为了写文件而希望提供一致性。但是Java Locale.ROOT和Locale.getDefault()是什么意思,它们通常如何映射到C#中的选项? 问题答案: 好吧,多亏了Andreas,我可以从javadoc中进行总结: 和 我只是希望该文档更容

  • 问题内容: LINQ的Java等效项是什么? 问题答案: 现在使用Java 8向我们介绍了Stream API,这在处理集合时是类似的事情,但与Linq不太一样。 如果它是您正在寻找的ORM,例如Entity Framework,那么您可以尝试Hibernate

  • 问题内容: 有Swift的等效项吗?在中,我们通常使用: 如何在Swift中实现相同目标?我发现了一个功能: 但是,它很长,根本不方便。 问题答案: 将在斯威夫特的世界同样存在。 的,和参数均标有 该装置的同时调用该函数我们可以忽略这些参数的关键字。在这种情况下,将使用其默认值。 这得出一个结论,该方法调用可以简化为: Swift 5- 没什么变化,仍然可以这样工作。