相关疑难解决方法(0)

Java中的静态块

前几天我查看了一些代码,我遇到了:

static {
    ...
}
Run Code Online (Sandbox Code Playgroud)

来自C++,我不知道为什么会这样.它不是一个错误,因为代码编译得很好.什么是"静态"代码块?

java static

304
推荐指数
5
解决办法
18万
查看次数

有没有办法从持有类名的字符串中实例化对象?

我有一个文件:Base.h

class Base;
class DerivedA : public Base;
class DerivedB : public Base;

/*etc...*/
Run Code Online (Sandbox Code Playgroud)

和另一个文件:BaseFactory.h

#include "Base.h"

class BaseFactory
{
public:
  BaseFactory(const string &sClassName){msClassName = sClassName;};

  Base * Create()
  {
    if(msClassName == "DerivedA")
    {
      return new DerivedA();
    }
    else if(msClassName == "DerivedB")
    {
      return new DerivedB();
    }
    else if(/*etc...*/)
    {
      /*etc...*/
    }
  };
private:
  string msClassName;
};

/*etc.*/
Run Code Online (Sandbox Code Playgroud)

有没有办法以某种方式将此字符串转换为实际类型(类),以便BaseFactory不必知道所有可能的Derived类,并为每个类都有if()?我可以用这个字符串生成一个类吗?

我认为这可以通过Reflection在C#中完成.C++中有类似的东西吗?

c++ inheritance factory instantiation

135
推荐指数
3
解决办法
8万
查看次数

"空"构造函数或析构函数是否会与生成的构造函数或析构函数执行相同的操作?

假设我们有一个(玩具)C++类,如下所示:

class Foo {
    public:
        Foo();
    private:
        int t;
};
Run Code Online (Sandbox Code Playgroud)

由于没有定义析构函数,因此C++编译器应该自动为类创建一个析构函数Foo.如果析构函数不需要清理任何动态分配的内存(也就是说,我们可以合理地依赖编译器给我们的析构函数),那么将定义一个空的析构函数,即.

Foo::~Foo() { }
Run Code Online (Sandbox Code Playgroud)

做与编译器生成的一样的事情?那个空构造函数怎么样 - 也就是说,Foo::Foo() { }

如果存在差异,它们存在于何处?如果没有,一种方法优于另一种方法吗?

c++ oop constructor destructor class

72
推荐指数
4
解决办法
3万
查看次数

什么是与Java静态块等效的C++习惯用法?

我有一个带有一些静态成员的类,我想运行一些代码来初始化它们(假设这段代码不能转换成简单的表达式).在Java中,我会这样做

class MyClass {
    static int myDatum;

    static {
        /* do some computation which sets myDatum */
    }
}
Run Code Online (Sandbox Code Playgroud)

除非我弄错了,C++不允许这样的静态代码块,对吧?我应该做什么呢?

我想要解决以下两个选项:

  1. 进程加载时(或加载此类的DLL时)会发生初始化.
  2. 初始化在首次实例化类时发生.

对于第二种选择,我在考虑:

class StaticInitialized {
    static bool staticsInitialized = false;

    virtual void initializeStatics();

    StaticInitialized() {
        if (!staticsInitialized) {
            initializeStatics();
            staticsInitialized = true;
        }
    }
};

class MyClass : private StaticInitialized {
    static int myDatum;

    void initializeStatics() {
        /* computation which sets myDatum */
    }
};
Run Code Online (Sandbox Code Playgroud)

但这是不可能的,因为C++(目前?)不允许初始化非const静态成员.但是,至少可以通过表达式将静态块的问题减少到静态初始化的问题......

c++ java initialization static-block equivalent

28
推荐指数
3
解决办法
1万
查看次数

防止链接器删除全局变量

我使用静态全局变量构造函数作为方便注册函数的技巧,这个想法是这样的:

typedef int (*FuncPtr)(int);

struct RegHelper
{
    RegHelper(const char * Name, FuncPtr Func)
    {
        Register(Name, Func);
    }
}

#define REGISTER(func) RegHelper gRegHelper_ ## func (#func, func);
Run Code Online (Sandbox Code Playgroud)

现在我可以这样注册函数(我用它来实现某种反射):

int Foo(int a)
{
    return a * 123;
}

REGISTER(Foo)

int Bar(int a)
{
    return a * 456;
}

REGISTER(Bar)
Run Code Online (Sandbox Code Playgroud)

问题是,如果我在静态库中使用它,有时链接器会检测到编译单元没有被使用,并且它会丢弃整个内容.所以全局变量没有构造,函数没有注册......

我的问题是:我可以做些什么来解决这个问题?在初始化期间调用每个编译单元中的虚函数似乎触发了全局变量的构造,但这并不觉得非常安全.还有其他建议吗?

c++ linker global-variables

12
推荐指数
1
解决办法
4451
查看次数

如何强制在库中包含"未使用的"对象定义

我的问题类似于这些,但似乎并没有完全相关:

如何在链接到可执行文件时强制将对象文件包含在静态库中?

使用MSVC强制符号导出

我得到的是这样的:

struct thingy;
struct container
{
  static container& instance(); // singleton

  int register_thingy(thingy*);
};

struct thingy
{
  virtual ~thingy() {}
  virtual int id() const = 0;
};

//template trick to force registration.
template < typename Derived >
struct registered_thingy : thingy
{
  registered_thingy() : my_id(my_static_id) {} 

  int id() const { return my_id; }
private:
  int my_id;
  static int my_static_id;
}
template < typename Derived >
int registered_thingy<Derived>::my_static_id = 
  container::instance().register_thingy(new Derived);
Run Code Online (Sandbox Code Playgroud)

现在,concrete_thingy.cpp我在一个文件中:

struct my_concrete_thingy : registered_thingy<my_concrete_thingy> …
Run Code Online (Sandbox Code Playgroud)

c++ linker

12
推荐指数
1
解决办法
5630
查看次数

析构函数:琐碎与隐含的定义

正如我理解标准一样,一个简单的析构函数是一个隐式声明的析构函数,它的类只有基本和非静态成员和简单的析构函数.鉴于此定义的递归性,在我看来,唯一的"递归停止"条件是找到具有非隐式声明的析构函数的基础或非静态成员(即用户声明).如果这是正确的,那应该意味着一个简单的析构函数是"不必做任何事情",因此它将被声明(隐式)但没有定义.用另一种方式说:根据标准定义,隐含定义的析构函数(即"它做某事")是不是很简单?

对不起那种愚蠢的问题,但我想在脑海中澄清一些事情......

c++ destructor

4
推荐指数
1
解决办法
4495
查看次数