C++ 单态模式析构函数C++;
我有这个单件模式,它运行正常。但是,当我使用valgrind执行程序以检查内存泄漏时,实例似乎从未被破坏 我的错在哪里 标题C++ 单态模式析构函数C++;,c++,singleton,valgrind,destructor,C++,Singleton,Valgrind,Destructor,我有这个单件模式,它运行正常。但是,当我使用valgrind执行程序以检查内存泄漏时,实例似乎从未被破坏 我的错在哪里 标题 类停止字{ 私人: 静态Stopwords*实例; 标准::地图迪乔纳里奥; 私人: 停止词(); 公众: ~Stopwords(); 公众: 静态停止字*getInstance(); std::map getMap(); }; .cpp Stopwords*Stopwords::instance=NULL; Stopwords::Stopwords(){ diccio
类停止字{
私人:
静态Stopwords*实例;
标准::地图迪乔纳里奥;
私人:
停止词();
公众:
~Stopwords();
公众:
静态停止字*getInstance();
std::map getMap();
};
.cpp
Stopwords*Stopwords::instance=NULL;
Stopwords::Stopwords(){
diccionario=map();
char nombre_archivo[]=“stopwords/stopwords.txt”;
ifstream archivo;
档案室开放(名称:档案室);
字符串停止字;
while(getline(archivo,stopword,,)){
diccionario[stopword]=1;
}
archivo.close();
}
Stopwords::~Stopwords(){
删除实例;
}
Stopwords*Stopwords::getInstance(){
if(实例==NULL){
instance=newstopwords();
}
返回实例;
}
map Stopwords::getMap(){
返回迪乔纳里奥;
}
这并不相关,但在初始化过程中,我从一个文件中读取了一堆单词,并将它们保存在一个map实例中
感谢您在析构函数中执行以下操作:
Stopwords::~Stopwords() {
delete instance;
}
我建议你补充:
Stopwords::~Stopwords() {
delete instance;
instance = 0;
}
此调用确保指针不仅从内存中删除,而且不指向任何内容。删除指针时,您需要确保它不再指向任何内容,否则可能会导致内存泄漏。问题在于,您从未手动调用析构函数或删除实例指针,即从类外部调用。所以析构函数中的删除永远不会执行,这意味着析构函数永远不会执行,这意味着删除永远不会执行,这意味着。。。你看到你在那里做了什么吗?你的析构函数正在间接地调用它自己,这不会很顺利。而且你从不从外面打电话给它,所以它根本就不会被呼叫——幸运的是 您应该更改您的单例实现,可能是Meyers单例(查找),或者最好根本不使用单例。在这种情况下,如果它们是数据源,那么该模式有太多的弱点需要处理
static
关键字来明确说明它在程序完成之前是活动的
static Singleton& getInstance()
{
static Singleton s;
return s;
}
可以通过在实例查看器中使实例静态函数STD::UnQuyQPTR而不是类静态变量来实现C++中的SuntLon。这确保在程序完成时调用析构函数,并允许您创建一个以多态方式访问的实例,例如通过指向抽象基类的指针
Stopwords::~Stopwords() {
delete instance;
}
这是类实例的析构函数。您可能打算在程序结束时调用此函数,好像它是一种“静态”析构函数,但事实并非如此
因此,Stopwords实例的析构函数启动Stopwords实例的销毁;这里有一个无限循环,你永远不会进入。如果你进入了这个循环,那么程序很可能会崩溃
有一种更简单的方法来实现单例:与其将实例保持为手动分配的静态类成员,不如将其保持为静态函数变量。C++将管理创建和销毁它。
class Stopwords {
public:
static Stopwords &getInstance() {
static Stopwords instance;
return instance;
}
~Stopwords();
std::map<std::string,short> getMap();
private:
Stopwords();
std::map<std::string,short> diccionario;
};
如果析构函数实际上不是从外部调用的,则这不会有任何帮助。他还可以使用std::unique_ptr而不是原始指针。此外,更好的方法是引用
实例,而不是将其作为指针,例如getInstance()中的返回&实例
@odedsh这将是一种可能的解决方案,因为unique\u ptr
析构函数将从外部隐式调用。每当调用getInstance时,都会创建并返回一个新实例?这不是违背了单例的目的吗?@EhsanAb不,每次调用getInstance
时,它都返回相同的对象。啊,我明白了/它是静态的。没有看到关于是否使用static t*实例
vsstatic t实例
的itA说明。如果T本身较大,则前者可能更可取,因为它进行堆分配而不是静态数据分配。这会使可执行映像的大小变小,在数据段中只保留sizeof(T*)
字节,而不是sizeof(T)
字节。@Rodrigo防止删除复制构造函数。
Stopwords::~Stopwords() {
delete instance;
}
class Stopwords {
public:
static Stopwords &getInstance() {
static Stopwords instance;
return instance;
}
~Stopwords();
std::map<std::string,short> getMap();
private:
Stopwords();
std::map<std::string,short> diccionario;
};
std::map<std::string,short> getMap() const;