C++中没有静态构造函数的理由是什么?

uujelgoq  于 2023-10-20  发布在  其他
关注(0)|答案(6)|浏览(160)

C++中没有静态构造函数的理由是什么?
如果允许的话,我们将在一个地方以一种非常有组织的方式初始化其中的所有静态成员,如下所示:

//illegal C++
class sample
{
public:

    static int some_integer;
    static std::vector<std::string> strings;

    //illegal constructor!
    static sample()
    {
       some_integer = 100;
       strings.push_back("stack");
       strings.push_back("overflow");
    }
};

在没有静态构造函数的情况下,很难有静态向量,并用值填充它,如上所示。static constructor很好地解决了这个问题。我们可以以一种非常有组织的方式初始化静态成员。
为什么C++没有静态构造函数?毕竟,其他语言(例如C#)有静态构造函数!

yshpjwxd

yshpjwxd1#

使用静态初始化顺序问题作为不引入此功能的借口一直是一个现状问题-它没有被引入是因为它没有被引入,人们一直认为初始化顺序是不引入它的原因,即使顺序问题有一个简单而非常直接的解决方案。
然而,如果人们真的想解决这个问题,他们会有一个非常简单和直接的解决方案:

//called before main()

int static_main() {

ClassFoo();
ClassBar();

}

适当的声明:

class ClassFoo {
 static int y;
  ClassFoo() {
   y = 1;
  }
}

class ClassBar {
  static int x;
  ClassBar() {
   x = ClassFoo::y+1;
  }
}

所以答案是,没有理由不存在,至少不是技术上的原因。

bttbmeg0

bttbmeg02#

这对c来说没有意义--类不是第一类对象(例如,java)。
A(静态|任何东西)构造函数意味着构造了什么-而c
类并没有构造,它们只是构造了。
你可以很容易地达到同样的效果:

//.h
struct Foo {
  static std::vector<std::string> strings;
};
//.cpp
std::vector<std::string> Foo::strings(createStrings());

在我看来,不需要再多一种语法方式来实现这一点。

xxe27gdn

xxe27gdn3#

静态对象将被放置在哪个翻译单元中?
一旦你考虑到静态数据必须放在一个(而且只有一个)TU中,那么剩下的路就不是“很难”了,并在函数中为它们赋值:

// .h
class sample
{
public:
    static int some_integer;
    static std::vector<std::string> strings;
};

//.cpp

// we'd need this anyway
int sample::some_integer;
std::vector<std::string> sample::strings;

// add this for complex setup
struct sample_init {
    sample_init() {
       sample::some_integer = 100;
       sample::strings.push_back("stack");
       sample::strings.push_back("overflow");
    }
} x;

如果你真的希望sample_init的代码出现在类sample的定义中,那么你甚至可以把它作为一个嵌套类放在那里。你只需要在定义静态对象的同一个地方定义它的示例(并且 * 在 * 它们已经通过它们的默认构造函数初始化之后,否则你当然不能push_back任何东西)。
C#是在C之后15-20年发明的,它有一个完全不同的构建模型。它提供了不同的特性,并且有些事情在C中不如在C#中简单,这并不奇怪。
C++0x增加了一个特性,可以更容易地用一些数据初始化向量,称为“初始化列表”。

nzkunb0c

nzkunb0c4#

你可以把你的“静态”成员放在他们自己的类中,用他们自己的构造函数来执行他们的初始化:

class StaticData
{
    int some_integer;
    std::vector<std::string> strings;

public:
    StaticData()
    {
       some_integer = 100;
       strings.push_back("stack");
       strings.push_back("overflow");
    }
}

class sample
{    
    static StaticData data;

public:
    sample()
    {

    }
};

静态data成员保证在首次尝试访问它之前被初始化。(可能在main之前,但不一定)

8yoxcaq7

8yoxcaq75#

静态意味着一个函数与一个对象无关。由于只有对象被构造,所以不清楚为什么静态构造器会有任何好处。
你总是可以在静态作用域中保存一个在静态块中构造的对象,但是你要使用的构造函数仍然会被声明为非静态的。没有规则表明你不能从静态作用域调用非静态方法。
最后,C++ / C定义程序的开始是当输入main函数时。在进入main函数之前调用静态块,作为设置所评估代码的“环境”的一部分。如果您的环境要求完全控制设置和拆除,那么很容易争辩说,它实际上不是一些环境夹具,而是程序的继承过程组件。我知道最后一点是某种代码哲学(它的基本原理可以有不同的解释),但是不应该把关键代码放在可执行文件正式开始将“完全控制”交给程序员编写的代码之前。

w41d8nur

w41d8nur6#

除了其他答案,我认为这个功能是必要的。静态构造函数必须在我们使用静态成员或创建对象之前被调用,即。在使用类之前。
我们正在做的是编写一个静态函数来初始化静态成员并调用该函数。所以,我认为有静态构造函数会更好。
How to initialize static members of a class?

相关问题