【问题标题】:Temporary objects in C and C++C 和 C++ 中的临时对象
【发布时间】:2021-10-24 02:39:17
【问题描述】:

C 代码

#include <stdio.h>

typedef struct
{
    int a;
}A;

int main()
{
    A(); // this line gives error
    return 0;
}

输出

Error: Expected identifier or '('

C++ 代码

#include <iostream>

struct A
{
    int a;

    A()
    {
        std::cout<<"Ctor-A\n";
    }

    ~A()
    {
        std::cout<<"Dctor-A\n";
    }
};

int main()
{
    A(); // creates temporary object and destroyed it 
    return 0;
}

输出

Ctor-A
Dctor-A

我知道“三法则”,但代码会变得复杂,如果我们不遵守该法则,大多数编译器都不会出错。所以我避免创建一个复制构造函数和一个重载的赋值运算符。

为什么A()/A{} 在 C++ 中创建临时对象,而在 C 中却没有?在 C 中创建临时对象的另一种方法是什么?

【问题讨论】:

  • C 中没有构造函数。
  • 结构在 C 中没有构造函数,所以没有什么是临时的。最接近的事情是只做“A a”,你会得到一个分配给 A 的堆栈。
  • @AbhishekMane:好的,这是真的,警告是合理的。表达式结果也没有在 C++ 中使用。
  • @AbhishekMane:C 中没有这样的连接。但是您在 C++ 中使用的语法 A() 是函数样式的强制转换/构造函数调用。 C 没有函数风格的强制转换。
  • @BenVoigt:复合文字在 C 中不是临时的。函数定义之外的那些具有静态存储持续时间,而那些内部具有通常的生命周期的自动存储持续时间。 C 中唯一的临时结构是包含数组的非左值结构或联合。这种临时可以由返回这种结构或联合(按值)的函数创建。当包含完整表达式的评估结束时,它的生命周期结束。

标签: c++ c struct constructor temporary-objects


【解决方案1】:

A() 在 C++ 代码中调用结构 A 的构造函数。但是,C 实际上不支持构造函数/析构函数,甚至对象(在 OOP 的意义上)。如您在 C 中描述的那样,创建临时对象的唯一方法是声明 A 类型的变量并等待它超出范围,为其分配的内存将从堆栈中弹出,或者分配一个变量在堆上并在下一行释放它。

【讨论】:

  • C [程序由不同类型的对象组成。
  • C 不支持类或面向对象的编程,结构是最接近 C 的。
  • C 中的对象与面向对象编程有什么关系?您写道 C 不支持对象。这是一个无效的声明。
  • Dylan Burn C 支持对象。所有 C 程序都由对象及其操作组成。您从其他上下文中获取了一个术语,并试图替换 C 中的术语对象。您的陈述无效。
  • "C programs create, destroy, access, and manipulate objects"。仅仅因为它们不是 OOP 对象并不意味着它们不是对象。
【解决方案2】:

这个表达式

A()

被 C 编译器视为函数调用。在 C++ 中,这样的表达式意味着调用构造函数,前提是 A 是类类型。

要在 C 中创建一个临时对象,您可以声明一个函数,例如

struct A { int a; } A( int x )
{
    struct A a = { .a = x };
    return a;
}

然后你可以调用该函数来创建一个 struct A 类型的临时对象

A( 10 );

这是一个演示程序。

#include <stdio.h>

struct A { int a; } A( int x )
{
    struct A a = { .a = x };
    return a;
}

int main(void) 
{
    struct A a = A( 10 );
    
    printf( "a.a = %d\n", a.a );
    
    return 0;
}

程序输出是

a.a = 10

【讨论】:

  • 您甚至可以使用return (struct A) { .a = x }; 稍微压缩代码而不会失去可读性。无论如何,考虑使用A(void) 以类似于OP 的方式使用A
【解决方案3】:

在 C(C99 及更高版本)中,您可以使用 Compound Literal 创建具有自动生命周期的结构。

语法是(A){ initializers, for, struct, members }

生命周期是自动的,而不是临时的,因此以这种方式创建的结构不会在完整表达式的末尾消失,而是在封闭范围的末尾。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-14
    • 2013-02-14
    • 1970-01-01
    • 2016-01-30
    • 1970-01-01
    相关资源
    最近更新 更多