为什么在C ++中没有“初始化”关键字,就像在Delphi中一样?

时间:2010-12-09 20:53:48

标签: c++ delphi initialization

在切换到C ++之前,我们发现Delphi中的initialization语言元素非常有用。它允许您在程序启动时调用每个单元中的代码,因此您可以初始化该单元的各种元素。

我们认为这样做更容易,并有助于保持代码清洁。

  • 那么为什么C ++中没有initializationfinalization

  • 我们有什么选择在C ++中替换此语言功能?

8 个答案:

答案 0 :(得分:7)

等效的C ++特性是文件范围/全局对象的构造函数和析构函数。例如:

#include <iostream>
using std::cout;

struct X {
   X() { cout << "X::X()\n"; }
   ~X() { cout << "X::~X()\n"; }
};

static X x;

int main() { cout << "main()\n"; return 0; }

将输出

X::X()
main()
X::~X()

跑步时。

使用此功能通常被认为是不明智的,因为您无法控制执行这些构造函数和析构函数的顺序,这意味着可能会在它们的依赖项之前初始化,从而产生难以调试的崩溃。 / p>

答案 1 :(得分:3)

在C ++中,构造函数/析构函数对通常用于此类事情。但是,在使用静态对象时要小心。如果你想这样做,你应该阅读两件事:

  1. What's the "static initialization order fiasco"?

  2. How do I prevent the "static initialization order fiasco"?

答案 2 :(得分:3)

问题1:为什么没有关键字?

除了Stroustrup或委员会成员之外没有人可以真正回答为什么C ++是这样的,但是我们可以推测,可能对于关键词来说它不够重要。 C ++标准确实讨论了初始化的顺序,例如对象,但是顺序没有严格定义并留给实现。这是一个引用(3​​.6.2 / 3):

  

是否是实现定义   或不是动态初始化   对象的(8.5,9.4,12.1,12.6.1)   命名空间范围是在之前完成的   主要的第一个声明。如果   初始化推迟到一些   第一次之后的时间点   主要陈述,应该发生   在第一次使用任何功能之前   或在其中定义的对象   翻译单位作为对象   初始化

问题2:如何实现Delphi initializationfinalization关键字的等效?

有两种选择。第一个已被其他海报提及,我不想复制他们的答案:声明某个范围内的对象(translation unit或命名空间),其构造函数和析构函数将被称为'sometime';在那里工作。

请注意,此顺序为实施定义,因此您已经处于不确定的区域。

第二个选项也依赖于编译器。您正在使用Delphi,所以我认为您正在使用C ++ Builder来编译C ++代码吗?如果是这样,C ++ Builder和其他一些编译器支持#pragma startup and #pragma exit pragmas。这些编译指示在程序启动或关闭时的某个时间调用方法。

我个人认为这是一个更简洁的解决方案,原因有两个:

  • 它确切地指明什么时候 会发生,我可以看到它写 在代码中

  • 它允许你拨打电话 功能,而不是使用 构造函数或析构函数。这是 更美观,让你写,比方说, initialization()finalization()方法 执行你的工作。 这可能会让您尽可能接近Delphi语法。

您可以使用这些编译指示调用过程(不接受任何参数并返回void),也可以选择使用64到255之间的数字指定何时应该发生。只有在初始化顺序或最终确定事项。首先调用更高的数字,保留0-63的优先级。例如:

void initialization(void) { foo = 3; bar = 5; /* Do useful work here */ }
#pragma startup initialization 200

void finalization(void) { foo = 0; bar = 0; /* Do useful work here */ }
#pragma exit finalization 200

调用链由链接器管理,如果使用更多特定于编译器的构造(例如weak packaging),则可能会遇到问题,但通常这是我推荐的技术。

答案 3 :(得分:2)

类具有可用于初始化和清理的构造函数和析构函数。

我认为你在C ++中最接近“代码单元”的是类。

答案 4 :(得分:1)

使用构造函数(initialization代码)和析构函数(finalization代码)编写一个类。声明此类的单例实例;构造函数将在启动时调用,并在程序关闭之前执行析构函数。

答案 5 :(得分:1)

通常情况下,它被视为C ++中的代码气味,具有需要构造或破坏的全局状态,即使你确实拥有它,你也只需声明一个在其构造函数中执行此操作的类并定义文件全局实例它的。

答案 6 :(得分:0)

在C ++中,您调用构造函数(相当于您的析构函数)与您的类名相同,析构函数与您的类相同,前缀为波浪号(〜):

Class Point {
    public:
    Point() {  }
    ~Point() { }
}

答案 7 :(得分:0)

C ++最接近的功能是静态变量(特别是静态成员变量)。

// A.h
class A
{
public:

private:
    static int someValue;
};

// A.cpp
int A::someValue = 2;

静态变量在程序启动时初始化。静态成员没有自动“终结”过程(您必须编写自己的清理函数并调用它)。