从成员变量更新类变量或调用类功能是给出运行时错误

Updating class variable or calling class function from member variable is giving runtime error

本文关键字:功能 运行时错误 调用 变量 成员 更新 类变量      更新时间:2023-10-16

我正在尝试实现更新,该更新将更新为所有Listerner类我正在使用类变量来计算侦听器的数量。 myClass 's正在扩展侦听器以从 updater class> class

聆听

当我尝试从成员函数中使用类函数更新类变量时,我会遇到运行时错误。请参考以下代码,并帮助我分类此问题

 #define MAX_LISTNERS 10
class Listner{
public: 
virtual void onUpdate() = 0;
};
class Updater {
    Listner* ptrListner[MAX_LISTNERS];
    static int count;
    public: 
     static void updateCount(){
        count++;
    }
    void registerListner(Listner* ptrListner){
        this->ptrListner[count] = ptrListner;
        this->updateCount(); //---> Runtime Error
    }
    void updateToListner(){
        for(int i=0;i<=count;i++){
        this->ptrListner[i]->onUpdate();
        }
    }
};
 int  Updater::count = 0;
class MyClass: public Listner{
    public:
     void onUpdate(){
        cout<<"update from MyClass";
     }
};  
class MyClass2: public Listner{
    public:
     void onUpdate(){
        cout<<"update from MyClass2";
     }};
int main() {
    MyClass* obj = new MyClass();
    MyClass2* obj2 = new MyClass2();
    Updater obj_updater;
    obj_updater.registerListner(dynamic_cast<Listner*>(obj));
    obj_updater.registerListner(dynamic_cast<Listner*>(obj2));
    obj_updater.updateToListner();
}

这里要考虑的几件事,因为这似乎有点不安全,而不是现代C 11方法。

  1. 使用RAII进行分配,即unique_ptr,而不是显式new/delete
  2. 使用std ::向量而不是C风格数组声明。您可以在运行时限制金额。这也为您提供了隐性的听众计数
  3. 让Updater类负责分配,工厂样式,这也使您可以尊重类型的安全

类似以下内容:

class Listner
{
    public:
        virtual void onUpdate() = 0;
};
class Updater
{
    using ListnerPtr = std::unique_ptr<Listner>;
    using Listners   = std::vector<ListnerPtr>;
    Listners m_listeners;
public:
    template < typename T >
    bool registerListner()
    {
        static_assert(std::is_base_of<Listner, T>::value, "T must be derived from Listner");
        if (m_listeners.size() >= 10)
            return false;
        m_listeners.emplace_back(std::make_unique<T>());
        return true;
    }
    void updateToListner()
    {
        std::for_each(m_listeners.begin(), m_listeners.end(), [](const Listners::value_type& item)
        {
            item->onUpdate();
        });
    }
};
class MyClass : public Listner
{
public:
    void onUpdate() override
    {
        std::cout << "update from MyClass" << std::endl;
    }
};
class MyClass2 : public Listner
{
public:
    void onUpdate() override
    {
        std::cout << "update from MyClass2" << std::endl;
    }
};
int main
{
    Updater obj_updater;
    obj_updater.registerListner<MyClass>();
    obj_updater.registerListner<MyClass2>();
    obj_updater.updateToListner();
    return 0
}