相关疑难解决方法(0)

Singleton实例声明为GetInstance方法的静态变量,它是否是线程安全的?

我已经看到了Singleton模式的实现,其中实例变量在GetInstance方法中被声明为静态变量.像这样:

SomeBaseClass &SomeClass::GetInstance()
{
   static SomeClass instance;
   return instance;
}
Run Code Online (Sandbox Code Playgroud)

我认为这种方法有以下积极方面:

  • 代码更简单,因为它的编译器只负责在第一次调用GetInstance时创建此对象.
  • 代码更安全,因为没有其他方法可以获取对实例的引用,但是使用GetInstance方法并没有其他方法来更改实例,而是在GetInstance方法中.

这种方法的不利方面是什么(除了这不是非常OOP-ish)?这是线程安全的吗?

c++ singleton design-patterns

30
推荐指数
2
解决办法
3万
查看次数

C++,静态与命名空间与单例

我已经在网上阅读了很多帖子和文章,但我找不到明确的答案.

我有一些具有类似用途的功能,我想要超出全局范围.其中一些需要公开,另一些应该是私有的(因为它们只是"公共"功能的辅助功能).另外,我不仅有函数,还有变量.它们只需要"私人"帮助函数,也应该是私有的.

现在有三种方式:

  • 创建一个静态的类(反对:潜在的"不能在没有对象的情况下调用成员函数" - 并不是所有东西都需要是静态的)
  • 制作单身类(反对:我需要对象)
  • 创建命名空间(没有私有关键字 - 为什么我要把它放在命名空间中呢?)

对我采取什么方式?结合其中一些方法的可能方法?

我想到了类似的东西:

  1. 制作单例,静态函数使用单例对象的辅助函数(这可能吗?我仍然在类中,但访问它的类型的对象)
  2. 在programm start调用的构造函数,初始化所有东西( - >确保静态可以从单例对象访问函数)
  3. 仅通过MyClass :: PublicStaticFunction()访​​问公共函数

谢谢.

c++ singleton static namespaces

30
推荐指数
2
解决办法
1万
查看次数

为什么如果它被删除则调用析构函数,如果没有删除则不调用它?

请考虑以下代码:

#include <iostream>

struct A 
{
    A(){ };
    ~A(){ std::cout << "~A::A()" << std::endl; };
};

struct B: A { };

B *b = new B; //Doesn't produce any side-effect.

int main(){ }
Run Code Online (Sandbox Code Playgroud)

DEMO

程序不会产生任何输出,这意味着不会调用析构函数.但是如果我们用说明delete符替换析构函数的主体,程序甚至不会编译.

#include <iostream>

struct A 
{
    A(){ };
    ~A() = delete; //{ std::cout << "~A::A()" << std::endl; };
};

struct B: A { };

B *b = new B; //Error: use of deleted function

int main(){ }
Run Code Online (Sandbox Code Playgroud)

DEMO

由于调用了删除的功能.那是在这种情况下被调用的析构函数.为什么会有这样的差异?

即使我们明确定义了B构造函数,它也不会起作用:

#include <iostream> …
Run Code Online (Sandbox Code Playgroud)

c++ destructor c++11

29
推荐指数
4
解决办法
3470
查看次数

使用指针和使用静态对象的Singleton实现之间的区别

编辑:对不起,我的问题不明确,为什么书籍/文章更喜欢实施#1而不是实施#2?

使用指针实现Singleton类与使用静态对象的实际优势是什么?为什么大多数书都喜欢这个

class Singleton
{
  private:

    static Singleton *p_inst;
    Singleton();

  public:

    static Singleton * instance()
    {
      if (!p_inst)
      {
        p_inst = new Singleton();
      }

      return p_inst;
    }
};
Run Code Online (Sandbox Code Playgroud)

在此

class Singleton
{
  public:
    static Singleton& Instance()
    {
        static Singleton inst;
        return inst;
    }

  protected:
    Singleton(); // Prevent construction
    Singleton(const Singleton&); // Prevent construction by copying
    Singleton& operator=(const Singleton&); // Prevent assignment
    ~Singleton(); // Prevent unwanted destruction
};
Run Code Online (Sandbox Code Playgroud)

c++ singleton design-patterns

24
推荐指数
3
解决办法
2万
查看次数

总是用C++创建类?

来自Java背景,对我来说,处理创建类的选择或者只是实现我可能需要的函数是新的.通常,在建模可能具有状态的东西时,这是毫无疑问的.

现在我正在实现一个没有main函数和静态成员函数的共享库.是否有些东西反对创建一个类来封装函数?

此外,我想在另一个文件中封装更多代码,尤其是辅助功能.执行代码总是相同的,并且它的状态不会改变,所以我想我会声明它们也是静态的 - 所以这里出现了同样的问题.

c++ static static-methods

17
推荐指数
3
解决办法
809
查看次数

如何在C++中编写Jon Skeet的Singleton代码?

在Jon的网站上,他在C#中使用了这个优雅设计的单例,如下所示:

public sealed class Singleton
{
    Singleton()
    {
    }

    public static Singleton Instance
    {
        get
        {
            return Nested.instance;
        }
    }

    class Nested
    {
        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static Nested()
        {
        }

        internal static readonly Singleton instance = new Singleton();
    }
}
Run Code Online (Sandbox Code Playgroud)

我想知道如何在C++中编写等效代码?我有这个,但我不确定它是否实际上具有与Jon相同的功能.(顺便说一下,这只是一个星期五的练习,不需要任何特别的东西).

class Nested;

class Singleton
{
public:
  Singleton() {;}
  static Singleton& Instance() { return Nested::instance(); }

  class Nested
  { 
  public:
    Nested() {;}
    static Singleton& instance() { …
Run Code Online (Sandbox Code Playgroud)

c# c++ singleton

14
推荐指数
2
解决办法
3224
查看次数

静态字段的析构函数.单身实现

因此,经典简单的Singleton实现如下:

class Singleton
{
private:
    static Singleton* singleton;
    Singleton() {}
public:
    static Singleton* getInstance();        
};
Run Code Online (Sandbox Code Playgroud)

cpp文件:

Singleton* Singleton::singleton = 0;

Singleton* Singleton::getInstance()
{
    if (!singleton)
    {
        singleton = new Singleton;
    }

    return singleton;
}
Run Code Online (Sandbox Code Playgroud)

我在这里看到的内存泄漏- "因为没有删除.但是在C++中没有静态析构函数,所以我们只是不关心这个内存泄漏?

c++ singleton static design-patterns

13
推荐指数
1
解决办法
8814
查看次数

C++静态成员函数和变量

我正在通过进行小型机器人模拟来学习C++,而我在类中的静态成员函数方面遇到了麻烦.

我的环境类定义如下:

class Environment {
    private:
        int numOfRobots;
        int numOfObstacles;

        static void display(); // Displays all initialized objects on the screen

    public:
        Robot *robots;
        Obstacle *obstacles;

        // constructor
        Environment();

        static void processKeySpecialUp(int, int, int); // Processes the keyboard events
};
Run Code Online (Sandbox Code Playgroud)

然后在构造函数中我初始化机器人和障碍物,如下所示:

numOfRobots = 1; // How many robots to draw
numOfObstacles = 1;
robots = new Robot[numOfRobots];
obstacles = new Obstacle[numOfObstacles];
Run Code Online (Sandbox Code Playgroud)

以下是使用这些变量的静态函数示例:

void Environment::display(void) {
    // Draw all robots
    for (int i=0; i<numOfRobots; i++) {
        robots[i].draw();
    }
}
Run Code Online (Sandbox Code Playgroud)

当我尝试编译时,我会收到类似的错误消息

error: …
Run Code Online (Sandbox Code Playgroud)

c++

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

C++ Move Semantics - 包装旧版C API

我正在使用传统的C API,在这种API下获取一些资源是昂贵的,并且释放该资源绝对是至关重要的.我正在使用C++ 14,我想创建一个类来管理这些资源.这是事物的基本骨架......

class Thing
{
private:
    void* _legacy;

public:
    void Operation1(...);
    int Operation2(...);
    string Operation3(...);

private:
    Thing(void* legacy) :
        _legacy(legacy)
    {
    }
};
Run Code Online (Sandbox Code Playgroud)

这不是单身模式.没有什么是静态的,可能有很多Thing实例,都在管理自己的遗留资源.此外,这不仅仅是一个智能指针.包裹的指针,_legacy是私有的,所有操作都是通过一些公共实例函数公开的,这些函数隐藏了消费者的遗留API.

构造函数是私有的,因为实例将从实际获取资源Thing的静态工厂或命名构造函数返回.这是对该工厂的廉价模仿,使用malloc()作为代码的占位符来调用遗留API ...

public:
    static Thing Acquire()
    {
        // Do many things to acquire the thing via the legacy API
        void* legacy = malloc(16);

        // Return a constructed thing
        return Thing(legacy);
    }
Run Code Online (Sandbox Code Playgroud)

这是析构函数,它负责释放遗留资源,同样,free()它只是一个占位符......

    ~Thing() noexcept
    {
        if (nullptr != _legacy)
        {
            // Do many …
Run Code Online (Sandbox Code Playgroud)

c++ constructor move c++11 c++14

11
推荐指数
2
解决办法
525
查看次数

我应该使用Initialize-on-demand习语,如果是这样的话?

我有以下代码:

 MyType x = do_something_dangerous();
 // ...
 if (some_condition) {
     // ...
     bar(x);
 }
 else { 
     // ...
 }
 // ...
 if (another_condition_which_may_depend_on_previous_if_else} {
     // ...
     baz(x);
 }
Run Code Online (Sandbox Code Playgroud)

这个想法是,在某些情况下,我可能需要使用,这可能是事先确定的难度/不方便x.但是在我不需要使用它的情况下,尝试初始化它可能是不好的(比如说,可能会导致我的进程崩溃).

现在,似乎我需要使用的是一个初始化按需持有者(链接侧重于Java,所以这里是一个草图):某种Wrapper<MyType>Wrapper<MyType, do_something_dangerous>一种get()方法,这样第一次get()调用do_something_dangerous(),后来get()只是通过第一次通话获得的价值.

  • 这确实是一种合适的方法吗?
  • 是否有一些标准(ish)实现这个成语,或者它的一个变体?

笔记:

  • 我可以使用boost::optional,但这有点麻烦,也扭曲了预期的用途:"建议optional<T>在没有类型的价值,T缺乏的地方,只有一个,清楚(对所有各方)的原因使用价值与任何常规价值一样自然T."

c++ idioms idiomatic

9
推荐指数
1
解决办法
425
查看次数