首页 > 解决方案 > 指向静态常量对象的共享指针?

问题描述

对于上下文,我正在实现一个用户访问系统,人们可以在其中登录到我的应用程序。当前登录的用户通过指向 a 的指针访问CUser

std::shared_ptr<CUser> m_pCurrentUser;

当用户注销时,我希望此指针指向我已声明为静态 const 的“默认”用户:

static const CUser xDefaultUser(L"Default", L"password", CUser::EAccessLevels::eAnon);

我的第一个问题是将 static const 应用于默认用户对象是否正确。我的理由是它永远不应该改变(const)并且我希望它在应用程序的生命周期内可用(静态)。

第二个问题是我应该如何将默认用户分配为m_pCurrentUser. 我应该改为声明 aconst shared_ptr<CUser>而不是直接的对象吗?

标签: c++c++11shared-ptr

解决方案


将指向静态对象的指针分配给 ashared_ptr不是一个好主意。你会得到内存损坏,因为 ptr 不拥有这个内存:

shared_ptr<CUser> ptr = &xDefaultUser;
ptr = nullptr; // crash

您可以static const shared_ptr使用默认对象创建。在这种情况下,内存不会被破坏。请参阅下面的示例:

#include <string>
#include <memory>
#include <iostream>

class User {
public:
    User(const std::string& name)
        : _name(name)
    {}
    ~User() { std::cout << "Bye, " << _name << std::endl; }
    void print() { std::cout << _name << std::endl; }
private:
    std::string _name;
};

static const std::shared_ptr<User> s_defaultUser = std::make_shared<User>("<default>");

class UserMgr {
public:
    UserMgr()
        : m_current(s_defaultUser)
    {}

    void MakeCurrent(std::shared_ptr<User> u) { 
        if (u) {
            m_current = u;
        } else {
            m_current = s_defaultUser;
        }
    }

    std::shared_ptr<User> GetCurrent() { return m_current; }
private:
    std::shared_ptr<User> m_current;   
};

int main() {
    UserMgr mgr;

    mgr.MakeCurrent(std::make_shared<User>("User 1"));
    mgr.GetCurrent()->print();
    mgr.MakeCurrent(std::make_shared<User>("User 2"));
    mgr.GetCurrent()->print();
    mgr.MakeCurrent(std::make_shared<User>("User 3"));
    mgr.GetCurrent()->print();
    mgr.MakeCurrent(nullptr);
    mgr.GetCurrent()->print();

    return 0;
}

Demo on coliru


推荐阅读