微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如果某些成员函数尚未被调用,是否可能产生编译时错误

如何解决如果某些成员函数尚未被调用,是否可能产生编译时错误

我正在用单例模式编写一个类。

class GroupListDAO {
public:
    static GroupListDAO* getInstance() {
        static GroupListDAO groupListDAO;
        return &groupListDAO;
    }

    init(server::MysqLdb::MysqLHelperTempalte* pHelper) {
        MysqLHT = pHelper;
    }

    bool getUserHeartNum(uint32_t owner,uint32_t& totalNum);
    bool setUserHeartNum(uint32_t owner,uint32_t totalNum,uint32_t update_time);
private:
    MysqLHelperTempalte *MysqLHT;

    GroupListDAO() = default;
    ~GroupListDAO() = default;
};

如你所见,这个类是用来连接MysqL的。因此,在调用任何其他成员函数之前,必须先初始化成员数据 MysqLHT

总之,类用户必须使用这个类如下:

GroupListDAO *p = GroupListDAO::getInstance();
p->init(XXX);    // init must be called before calling any other member functions
p->getUserHeartNum(...);
p->setUserHeartNum(...);

所以我在想是否有办法强制类用户调用函数init。这意味着如果类用户代码如下:

GroupListDAO *p = GroupListDAO::getInstance();
p->getUserHeartNum(...);
p->setUserHeartNum(...);

可能会产生一些编译时错误

Ofc,你可能会说我们可以在其他成员函数if (MysqLHT == nullptr) { throw exception; },但这会是运行时错误,而不是编译时错误

真实案例

一个大型项目由 5 个开发人员开发。他们都在使用一些 Singleton 对象。但他们必须说:嘿,我已经初始化了,你们可以在代码中使用它。或者,对不起,我们都忘记初始化了...

解决方法

正如评论中所建议的,您可以使用带有默认值的参数:

C:\Program Files\Python36

一方面,让调用者传递参数但只在第一次调用时使用它并不好。另一方面,您的设计表明有一个地方您知道它是对 getInstance(server::mysqldb::MysqlHelperTempalte* pHelper = nullptr) 的第一次调用(您不想 getInstance 两次,对吗?)。因此我建议:

init

class GroupListDAO { public: static GroupListDAO* createInstance(server::mysqldb::MysqlHelperTempalte* pHelper) { return getInstance(pHelper); } static GroupListDAO* getInstance() { return getInstance(nullptr); } private: static GroupListDAO* getInstance(server::mysqldb::MysqlHelperTempalte* pHelper = nullptr) { static GroupListDAO groupListDAO(pHelper); return &groupListDAO; } }; 可能需要成为实际对象的包装器,并且可以在使用 GroupListDAO 调用时抛出其构造函数。我不知道创建编译器错误的简单方法。


PS:实际上我认为您有相互冲突的要求。一方面,您需要一个对调用者隐藏初始化的单例。可以通过 nullptr 获取实例,无需关心初始化。另一方面,您确实想关心初始化,因为对 getInstance 的第一次调用是“特殊的”。单例模式和使用 getInstance 方法都不是孤立的完美习惯用法。当一起使用时,它们会更糟。我并不是说这是绝对不行的,但在两种方法都应该保留的情况下必须做出妥协也就不足为奇了。

,

如果你真的想要一个编译错误,你就必须摆脱你的单例模式:

class GroupListDao
{
public:
  GroupListDao(...) { /* do your initialization here */ }

  bool getUserHeartNum(uint32_t owner,uint32_t& totalNum);
  bool setUserHeartNum(uint32_t owner,uint32_t totalNum,uint32_t update_time); 
  // ...
}

这样可以确保 GroupListDao 的任何实例都已初始化。然后你必须在你的代码中传递这个实例。因此,您不再能确定在编译时您的应用程序中只有一个 GroupListDao 实例(如果您确实需要,您可以在构造函数中跟踪已创建实例的数量并在运行时引发错误)。 选择你的毒药 ;)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。