Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C+的最佳实践+;复杂静态初始化逻辑 我在java中很长,对C++比较陌生。因此,在Java中,如果在类级别有一些复杂的静态对象(在Java中,一切都在类级别),我们可以简单地使用一个静态块来初始化它。例如 public class MyClass extends MyBase { public static final Map<String, AComplexClass> STATIC_MAP = new HashMap<String, AComplexClass> (); static { AComplexClass first = ComplexClassFactory.createComplexType1(); first.configure("Something", "Something"); STATIC_MAP.put("key1", first); // do some more } } 公共类MyClass扩展MyBase{ 公共静态最终映射static_Map=newhashmap(); 静止的{ AComplexClass first=ComplexClassFactory.createComplexType1(); 首先,配置(“某物”、“某物”); 静态映射放置(“键1”,第一); //多做点 } } 但是,如果初始化C++静态变量的限制,如果我想定义相同的 StistalPixP< ,这可能太复杂了,我需要在 .CPP < /C>文件中为每个< AComplexClass > 对象命名变量,然后放到地图上,在代码中创建了相当多的垃圾,也有可能让其他类意外引用它们 < C++静态均衡逻辑的最佳实践是什么?我想这是相同的策略,但可能是其他风格_Java_C++_Static - Fatal编程技术网 文件中为每个< AComplexClass > 对象命名变量,然后放到地图上,在代码中创建了相当多的垃圾,也有可能让其他类意外引用它们 < C++静态均衡逻辑的最佳实践是什么?我想这是相同的策略,但可能是其他风格,java,c++,static,Java,C++,Static" /> 文件中为每个< AComplexClass > 对象命名变量,然后放到地图上,在代码中创建了相当多的垃圾,也有可能让其他类意外引用它们 < C++静态均衡逻辑的最佳实践是什么?我想这是相同的策略,但可能是其他风格,java,c++,static,Java,C++,Static" />

C+的最佳实践+;复杂静态初始化逻辑 我在java中很长,对C++比较陌生。因此,在Java中,如果在类级别有一些复杂的静态对象(在Java中,一切都在类级别),我们可以简单地使用一个静态块来初始化它。例如 public class MyClass extends MyBase { public static final Map<String, AComplexClass> STATIC_MAP = new HashMap<String, AComplexClass> (); static { AComplexClass first = ComplexClassFactory.createComplexType1(); first.configure("Something", "Something"); STATIC_MAP.put("key1", first); // do some more } } 公共类MyClass扩展MyBase{ 公共静态最终映射static_Map=newhashmap(); 静止的{ AComplexClass first=ComplexClassFactory.createComplexType1(); 首先,配置(“某物”、“某物”); 静态映射放置(“键1”,第一); //多做点 } } 但是,如果初始化C++静态变量的限制,如果我想定义相同的 StistalPixP< ,这可能太复杂了,我需要在 .CPP < /C>文件中为每个< AComplexClass > 对象命名变量,然后放到地图上,在代码中创建了相当多的垃圾,也有可能让其他类意外引用它们 < C++静态均衡逻辑的最佳实践是什么?我想这是相同的策略,但可能是其他风格

C+的最佳实践+;复杂静态初始化逻辑 我在java中很长,对C++比较陌生。因此,在Java中,如果在类级别有一些复杂的静态对象(在Java中,一切都在类级别),我们可以简单地使用一个静态块来初始化它。例如 public class MyClass extends MyBase { public static final Map<String, AComplexClass> STATIC_MAP = new HashMap<String, AComplexClass> (); static { AComplexClass first = ComplexClassFactory.createComplexType1(); first.configure("Something", "Something"); STATIC_MAP.put("key1", first); // do some more } } 公共类MyClass扩展MyBase{ 公共静态最终映射static_Map=newhashmap(); 静止的{ AComplexClass first=ComplexClassFactory.createComplexType1(); 首先,配置(“某物”、“某物”); 静态映射放置(“键1”,第一); //多做点 } } 但是,如果初始化C++静态变量的限制,如果我想定义相同的 StistalPixP< ,这可能太复杂了,我需要在 .CPP < /C>文件中为每个< AComplexClass > 对象命名变量,然后放到地图上,在代码中创建了相当多的垃圾,也有可能让其他类意外引用它们 < C++静态均衡逻辑的最佳实践是什么?我想这是相同的策略,但可能是其他风格,java,c++,static,Java,C++,Static,这是一个组织问题。我不确定每个人都会同意哪一个“最佳实践”,但这就是我将如何处理您试图做的事情 首先是线路 public static final Map<String, AComplexClass> STATIC_MAP = new HashMap<String, AComplexClass> (); 这会带来一些开销,但这是非常小的,除非您创建的对象数量惊人 选项2:用于设置变量的factory/friend类 如果您有另一个类,它显然负责创建您的类(例如工厂模式)

这是一个组织问题。我不确定每个人都会同意哪一个“最佳实践”,但这就是我将如何处理您试图做的事情

首先是线路

public static final Map<String, AComplexClass> STATIC_MAP = new HashMap<String, AComplexClass> ();
这会带来一些开销,但这是非常小的,除非您创建的对象数量惊人

选项2:用于设置变量的factory/friend类

如果您有另一个类,它显然负责创建您的类(例如工厂模式),那么您可以将该类作为朋友,并让它设置值。然而,这假定每个类只有一个这样的工厂——尽管通常情况下是这样的


正如您所拥有的,您不需要友好位来使用此选项-但我要说的是,一般来说,您可能不希望非
常量
静态是公共的。这是一种无法追踪的混乱,因为任何东西都可能在程序中的任何地方修改它们。

我缺少一点:使静态映射保持不变。不能在常量映射上使用运算符[],因为如果查找的键不存在,映射将使其生效。当心。C++与java映射的巨大区别。
#include<iostream>
#include <map>
#include <memory>

//Need a class for the example
class AComplexClass
{
public:
    virtual ~AComplexClass()
    {

    }
    // just to give it something to do. It is a complex class after all.
    virtual std::string toString() = 0;
};

// Doing this with a map<string, AComplexClass> is trivial. 
// To make things a bit nastier, let's throw in some abstraction!
class ChildOfAComplexClass: public AComplexClass
{
public:
    std::string toString()
    {
        return " Howdy! I'm a child of AComplexClass!";
    }
};

// shared_ptr will take care of the garbage collection since we're passing
// around a hierarchy of complex classes. Normally you wouldn't bother with
// a pointer and let map handle all of the allocation/deallocation, but I 
// wanted to make this example hard.

// OK. Non-trivial. 

// OK. It's still trivial.

// How much blood do you want from me?
std::shared_ptr<AComplexClass> AComplexClassFactory()
{
    return std::shared_ptr<AComplexClass>(new ChildOfAComplexClass());
}

// The main event! Declare and load up the map.
std::map<std::string, std::shared_ptr<AComplexClass>> STATIC_MAP
{
    {"one", AComplexClassFactory()},
    {"two", AComplexClassFactory()},
    {"three", AComplexClassFactory()},
    {"four", AComplexClassFactory()}
};

// And a quick test to prove it works.
int main()
{
    std::cout << STATIC_MAP["one"]->toString() << std::endl;
    return 0;
}
#包括
#包括
#包括
//需要一个类作为示例
类A复杂类
{
公众:
虚拟~AComplexClass()
{
}
//只是让它做点什么。毕竟它是一个复杂的类。
虚拟std::string toString()=0;
};
//使用地图执行此操作非常简单。
//为了让事情变得更糟糕,让我们加入一些抽象概念!
类complexClass的子类:公共AComplexClass
{
公众:
std::string toString()
{
return“你好!我是一个复杂类的孩子!”;
}
};
//自从我们经过后,shared_ptr将负责垃圾收集
//围绕复杂类的层次结构。通常情况下,你不会为这个问题烦恼
//一个指针,让map处理所有的分配/解除分配,但是我
//我想让这个例子变得很难。
//嗯。不平凡。
//嗯。这仍然是微不足道的。
//你想从我这里得到多少血?
std::shared_ptr AComplexClassFactory()
{
返回std::shared_ptr(complexClass()的新子级);
}
//主要事件!声明并加载地图。
std::map静态映射
{
{“一”,AComplexClassFactory()},
{“两个”,一个复杂的ClassFactory()},
{“三”,一个复杂的ClassFactory()},
{“四”,AComplexClassFactory()}
};
//还有一个快速测试来证明它的有效性。
int main()
{
.cpp文件中的std::cout-toString()静态初始化
<>你可以在C++中做类似的事情,但是你需要在.cpp文件中进行初始化。你可以将初始化推迟到函数中,这样你就可以做任何你想要的初始化:

MyClass.h

#pragma once
#include <unordered_map>
#include <string>
#include "AComplexClass.h"

using MyMap = std::unordered_map<std::string, AComplexClass>;

class MyClass {
public:
  const static MyMap STATIC_MAP;
};
#pragma once
#include <unordered_map>
#include <string>
#include "AComplexClass.h"

using MyMap = std::unordered_map<std::string, AComplexClass>;

MyMap createMap() {
  // as before ...
}

class MyClass {
public:
  static const AComplexClass& STATIC_MAP(const std::string& key) {
    const static MyMap map = createMap();

    // Could return the map by reference but may as well use it in this
    // function to make the syntax slightly simpler for the calling code.
    return map.at(key);
  }
};
main.cpp

#include "MyClass.h"

namespace {    
  MyMap createMap() {
    MyMap map;
    auto first = createComplexType1();
    first.configure("Something", "Something");

    map.emplace("key1", std::move(first));

    // do some more

    return map;
  }
}

const MyMap MyClass::STATIC_MAP = createMap();
#include "MyClass.h"

int main() {
  auto object = MyClass::STATIC_MAP.at("key1");
}
#include "MyClass.h"

int main() {
  auto object = MyClass::STATIC_MAP("key1");
}
因为
operator[]
需要非常量访问,所以我改用了
at()

您需要注意的一件事是,这基本上意味着您应该避免依赖于另一个.cpp文件中的任何静态初始化

静态局部变量 避免静态初始化顺序失败的一种方法是使映射成为函数中的静态局部变量。这还有一个好处,即如果您希望:

MyClass.h

#pragma once
#include <unordered_map>
#include <string>
#include "AComplexClass.h"

using MyMap = std::unordered_map<std::string, AComplexClass>;

class MyClass {
public:
  const static MyMap STATIC_MAP;
};
#pragma once
#include <unordered_map>
#include <string>
#include "AComplexClass.h"

using MyMap = std::unordered_map<std::string, AComplexClass>;

MyMap createMap() {
  // as before ...
}

class MyClass {
public:
  static const AComplexClass& STATIC_MAP(const std::string& key) {
    const static MyMap map = createMap();

    // Could return the map by reference but may as well use it in this
    // function to make the syntax slightly simpler for the calling code.
    return map.at(key);
  }
};
静态局部变量将在第一次使用时初始化。

已经有了正确的答案,但可以改进

<>在C++中,你也可以静态初始化成员,让我们把java类转换成C++:
class MyClass : public MyBase {
public:
    static std::map<std::string, AComplexClass> STATIC_MAP;
};

在Java类中,将其看作“代码>静态< /Cord>Bug”,但在上面的代码中显示了C++的新特性,因为C++ 11标准可以使用一个SO来为java类的容器填充容器,我们传递了一组“代码”> {键,值}对。

std::map
构造函数。键是文本字符串
“key?”
,值是
createComplexType1
返回的值

从类的定义中分离静态初始化允许我们在代码文件(cpp)而不是头文件(h)中执行此初始化,这样做有一些优点,比如更整洁的代码和隐藏类细节的可能性

静态映射的初始化和生存期绑定到静态映射:

静态存储持续时间。对象的存储在程序开始时分配,在程序结束时解除分配。仅存在一个对象实例。在命名空间范围(包括全局命名空间)声明的所有对象都具有此存储持续时间,以及使用静态或外部声明的对象


你可以看到一个现场演示。

只是对@ChrisDrew关于使用额外函数的回答的一句评论
std::map<std::string, AComplexClass> MyClass::STATIC_MAP
{
    {"key1", ComplexClassFactory::createComplexType1("Something", "Something")},
    {"key2", ComplexClassFactory::createComplexType1("Foo",       "Bar")},
    {"key3", ComplexClassFactory::createComplexType1("Epi",       "Blas")},
    {"key4", ComplexClassFactory::createComplexType1("Mortadelo", "Filemon")},
    {"key5", ComplexClassFactory::createComplexType1("Asterix",   "Obelix")},
};
//.cpp
vector<int> MyClass::v = [](){vector<int> v; v.reserve(100); return v;}();