是否可以从静态初始化块内部获取类类型?
这是我目前拥有的简化版本::
class Person extends SuperClass {
String firstName;
static{
// This function is on the "SuperClass":
// I'd for this function to be able to get "Person.class" without me
// having to explicitly type it in but "this.class" does not work in
// a static context.
doSomeReflectionStuff(Person.class); // IN "SuperClass"
}
}
Run Code Online (Sandbox Code Playgroud)
这更接近我正在做的事情,即初始化一个保存有关对象及其注释等信息的数据结构......也许我使用了错误的模式?
public abstract SuperClass{
static void doSomeReflectionStuff( Class<?> classType, List<FieldData> fieldDataList ){
Field[] fields = classType.getDeclaredFields();
for( Field field : fields ){
// Initialize fieldDataList
}
} …Run Code Online (Sandbox Code Playgroud) 这是一个与 C++ 中对象初始化相关的问题。
我有一组类(不是实例),它们继承自一个公共基类,我需要它们在程序启动时在容器(特别是地图)中注册有关它们自己的信息。
问题是我需要它是动态的。容器定义在一个独立的项目中,不同于类。我宁愿避免制作库的多个硬编码版本,每个使用它的程序中的每一组类都有一个。
我想过在每个子类中都有一个特殊类的静态实例,这将在其构造函数中进行注册。但是,我发现没有办法保证在构造这些对象之前构造容器。
我还应该注意,在创建这些子类的任何实例之前,容器中关于子类的信息应该可用。
有没有办法做到这一点,或者在一般情况下模仿 C++ 中的静态构造函数?
我正在使用一些静态库构建我的程序(实际测试).
这个库包含一个文件,我在其中有这样的函数:
string& GetString() {
static string strFilename;
return strFilename;
}
void PrintToScreen() {
printf("String: %s\n", GetString().c_str())
}
Run Code Online (Sandbox Code Playgroud)
然后在我的main.cpp(库外)我正在做:
GetString() = "abc";
printf("String: %s\n", GetString().c_str());
PrintToScreen();
Run Code Online (Sandbox Code Playgroud)
我得到这个输出:
String: abc
String:
Run Code Online (Sandbox Code Playgroud)
所以看起来像是对函数的第二次调用(但是从库中的不同文件完成)以某种方式清除以前的值,重新初始化它,或者使用它自己的副本.
我更改了GetString函数以使用'new'但结果完全相同(btw.程序从不崩溃).
但我不明白热可能吗?
我有什么想法我做错了吗?
-------------------------------更新------------------ ------------
0000000000000030 T _Z16GetLogprintfFilev
0000000000000008 b _ZGVZ16GetLogprintfFilevE16strLogprintfFile
0000000000000018 b _ZZ16GetLogprintfFilevE16strLogprintfFile
U _Z16GetLogprintfFilev
并且在我的基础库上使用nm(由最终的lib使用),我得到:
0000000000000030 T _Z16GetLogprintfFilev
0000000000000008 b _ZGVZ16GetLogprintfFilevE16strLogprintfFile
0000000000000018 b _ZZ16GetLogprintfFilevE16strLogprintfFile
是否有可能在应用程序启动时"自动"初始化静态类?我自动意思是不需要引用属性.
我希望能够做到这一点的原因是我想在启动时自动设置应用程序的主题.
这是一个简短的片段:
static class Settings{
private static Theme _defaultTheme;
public static Theme DefaultTheme{
get{
return _defaultTheme;
}
private set{
_defaultTheme = value;
ThemeManager.SetTheme(value);
}
}
static Settings(){
DefaultTheme = Themes.SomeTheme;
}
}
Run Code Online (Sandbox Code Playgroud)
我知道我可以(现在就是这样)和原来的getter/setter一起去打电话
ThemeManager.SetTheme( Settings.DefaultTheme );
Run Code Online (Sandbox Code Playgroud)
在App的构造函数(它是WPF项目)中它会完成这项工作,但是,至少从我的观点来看(如果我错了请纠正我),更适合默认主题应用而不是需要明确说明它.
c# static-constructor static-classes static-initialization static-class
public class Test {
public static void main(String[] args) {
System.out.println(Hello.a1);
}
}
class Hello {
static final int a1=10;
static {
System.out.println("SB");
}
}
Run Code Online (Sandbox Code Playgroud)
此代码始终打印10但不打印SB.为什么?
其实问题出在标准草案N4582中的一句话:
[basic.start.static/3] 允许实现将具有静态或线程存储持续时间的变量初始化为静态初始化,即使此类初始化不需要静态完成,前提是
— 初始化的动态版本在初始化之前不会更改任何其他静态或线程存储持续时间对象的值,并且
— 如果所有不需要静态初始化的变量都被动态初始化,则初始化的静态版本在初始化变量中产生的值与动态初始化产生的值相同。
这些话是不是意味着如果满足这两个条件,类类型的非局部变量可能会被完全静态初始化(零初始化),这样它的构造函数就不会被调用(因为动态版本,通过调用构造函数初始化,可能被静态版本取代)?
当您dlopen()是共享对象时,是否有一种机制可以让该 DLL 中的代码在不被显式调用的情况下执行?具体来说,调用者dlopen()可能不知道的全局变量/静态变量的 C++ 静态初始化代码?我很确定答案应该是“是”,但我不记得是什么机制导致这种情况发生,以及如何利用它来运行任意代码。
c++ shared-objects dynamic-loading dlopen static-initialization
我试图了解静态初始化顺序失败何时是一个真正的问题。如果我使用如下所示的字符串常量,kName它会遇到静态初始化顺序失败的问题吗?Derived在这种情况下这是一个问题吗,因为可以在kName初始化之前创建的实例,如 中 所示main.cpp?
// Base.cpp
namespace test {
class Base {
public:
virtual ~Base() = default;
protected:
explicit Base(const std::string &name);
};
} // namespace test
// Derived.cpp
namespace test {
static const std::string kName = "my name";
class Derived : public Base {
public:
Derived() : Base(kName) {}
~Derived() override = default;
};
} // namespace test
// main.cpp
int main() {
test::Derived instance{};
return 0;
}
Run Code Online (Sandbox Code Playgroud) C++ 中一个众所周知的问题是静态初始化顺序失败。当使用C++17 静态内联成员时,它仍然被认为是一个问题吗?
这是一个示例,其中静态内联成员在两个不同的翻译单元(a.cpp 和 b.cpp)中用作两个非内联静态成员的初始化程序:
计数器.hh
#pragma once
#include <vector>
#include <fstream>
class Counter
{
public:
Counter() { std::ofstream os("o.txt", std::ofstream::app); os << "Counter created" << std::endl; }
~Counter() { std::ofstream os("o.txt", std::ofstream::app); os << "Counter destroyed" << std::endl; }
void add_instance()
{
++m_instances;
std::ofstream os("o.txt", std::ofstream::app); os << "Counter increased: " << m_instances << std::endl;
}
void remove_instance()
{
--m_instances;
std::ofstream os("o.txt", std::ofstream::app); os << "Counter decreased: " << m_instances << std::endl;
}
private: …Run Code Online (Sandbox Code Playgroud) Context:java.io.File类有一个静态内部类方法如下:
LazyInitialization.temporaryDirectory();
Run Code Online (Sandbox Code Playgroud)
[编辑添加更多代码]我的代码最终调用上面的代码行.从temporaryDirectory()方法中抛出异常,在我的上下文中很好/期望.
try {
File tempFile = File.createTempFile("aaa", "aaa");
} catch (Exception e) {
// handle exception
}
Run Code Online (Sandbox Code Playgroud)
然后,当我再次调用相同的方法(createTempFile)时,我得到一个"java.lang.NoClassDefFound错误 - 无法初始化类java.io.File $ LazyInitialization"
问题:我假设在调用静态方法时,类加载器应该已经加载了内部类LazyInitialization,即使内部方法引发了异常.然而,为什么我在第二次调用时看到NoClassDefFound错误?原始假设不正确吗?
c++ ×6
java ×3
c# ×1
c++11 ×1
c++17 ×1
dlopen ×1
linker ×1
reflection ×1
static ×1
static-class ×1