C++语言和单例的特性决定了单例不可继承。
单例有如下几项要求:
1. 构造函数为私有,或者至少不可以被此类的继承体系以外的类访问当,即要么是private,最坏也是protected
2. 构造函数只被调用一次,以初始化static对象。
所以如果B1,B2,继承至单例A,则不可以实现在程序运行的整个过程中既有一个B1单例又有一个B2单例,而且两个单例不存在依赖关系,原因是B1、B2共享一个A基类,而B1和B2的静态对象声明在A中,即两者共享一个base静态对象,因此对B1和B2两次调用初始化函数(GetInstance)时候,实际上基类A的静态对象会有两次初始化的动作(GetInstance),当然,基类的静态对象只会实例化一次,具体实例化位子类的B1还是B2类型,要看两个子类实例化调用的先后次序。
所以即使两个实例化都第一次调用GetInstance,也只实例化了一份静态对象,并且被两个类共享。这样的单例没有意义。
#include <iostream>
using namespace std;
class CSingleton
{
public:
static CSingleton * GetInstance()
{
//if(NULL == m_pInstance)
// m_pInstance = new CSingleton();
//return m_pInstance;
}
static void Release() //必须,否则会导致内存泄露
{
if(NULL != m_pInstance)
{
delete m_pInstance;
m_pInstance = NULL;
}
}
virtual void printfname()
{
printf("name : CSingleton\n");
}
protected:
CSingleton()
{
cout<<"CSingleton"<<endl;
};
static CSingleton * m_pInstance;
};
CSingleton* CSingleton::m_pInstance = NULL;
class CSingleDraw:public CSingleton
{
public:
static CSingleDraw* GetInstance()
{
if(NULL == m_pInstance)
m_pInstance = new CSingleDraw();
return (CSingleDraw*)m_pInstance;
}
virtual void printfname()
{
printf("name : CSingleDraw\n");
}
protected:
CSingleDraw()
{
cout<<"CSingleDraw"<<endl;
}
};
class CSingleDraw1:public CSingleton
{
public:
static CSingleDraw1* GetInstance()
{
if(NULL == m_pInstance)
m_pInstance = new CSingleDraw1();
return (CSingleDraw1*)m_pInstance;
}
virtual void printfname()
{
printf("name : CSingleDraw1\n");
}
protected:
CSingleDraw1()
{
cout<<"CSingleDraw"<<endl;
}
};
int main()
{
//CSingleton *x = CSingleton::GetInstance();
CSingleDraw* s1 = CSingleDraw::GetInstance();
CSingleDraw1* s2 = CSingleDraw1::GetInstance();
//x->printfname();
s1->printfname();
s2->printfname();
s1->Release();
system("pause");
return 0;
分享到:
相关推荐
在C++中,继承是实现多态性的重要手段,但过度或不适当的继承可能会带来问题。首先是性能代价,继承会导致类的大小增加,如果基类包含大量数据成员,派生类会占用更多内存。此外,虚函数表的引入也可能会影响运行时...
类模板的单例模式允许我们将单例行为泛化到任意类型,只需为每个需要单例的类继承这个模板,即可轻松实现单例。例如,如果我们有`Display`和`Scanner`两个类需要实现单例,可以这样做: ```cpp class Display : ...
总的来说,这个C++物品销售系统是面向对象设计的一个实例,通过类的封装、继承和多态实现了功能模块化,增强了代码的复用性和可扩展性。同时,采用单例模式管理和访问数据,确保了数据的一致性。项目的结构和文件...
10. **测试与调试**:开发过程中,单元测试和调试是必不可少的。开发者可能使用GTest等框架编写测试用例,以确保各个功能的正确性,并使用GDB等工具进行调试。 总的来说,"图书馆管理系统(C++)"是一个涵盖了C++...
此外,C++11及后续标准引入的新特性,如右值引用、自动类型推断、lambda表达式等,也是现代C++编程不可或缺的知识。 2. **Visual Studio IDE**:Visual Studio提供了丰富的工具和功能,支持代码编辑、调试、版本...
C++单例模式 用C++设计一个不能被继承的类 如何定义一个只能在堆上定义对象的类?栈上呢 重类构造和析构的顺序 操作系统 计算机操作系统复习 linux 服务器 Linux 网络编程复习 计算机网络 计算机网络总复习 数据库 ...
无论是对于想要深入了解C++语言特性的开发者,还是希望提高自己编程技能的专业人士而言,这本书都是一本不可或缺的参考书。通过对本书的学习,读者不仅能掌握C++语言的基础知识,还能学会如何运用这些知识来设计高...
1. **模块化编程**:在大规模程序设计中,模块化是必不可少的。C++支持通过命名空间、类和头文件来组织代码,有效地管理依赖关系,提高代码的可读性和可重用性。理解如何正确地使用#include指令以及头文件屏障...
书中详细介绍了类、对象、封装、继承和多态等核心概念,让读者理解如何通过面向对象设计来构建可维护、可扩展的软件系统。 2. **模板与泛型编程**:C++的模板允许开发者创建通用代码,提高代码重用性。书中探讨了...
4. 非侵入式设计:C++支持设计模式,如工厂模式、单例模式等,这些模式允许在不改变现有代码的情况下添加新功能。 四、C++的编译和链接 C++源代码首先通过编译器转换为汇编代码,再汇编成目标代码。多个目标代码...
STL是C++编程中不可或缺的一部分,能极大提高代码的效率和可读性。 书中还会讨论模板,这是C++的一个强大特性,允许创建泛型代码,使代码更具复用性和灵活性。此外,还将介绍异常处理,这是C++中错误处理的关键机制...
在信息技术领域,数据管理是至关重要的,尤其是在教育行业中,学生信息管理系统作为教育机构日常运营的基础工具,扮演着不可或缺的角色。本项目以"学生信息管理系统 使用C++完成"为主题,通过VC++开发环境,实现了对...
最后,《Thinking in C++》还涵盖了设计模式,这些模式是解决常见编程问题的成熟解决方案,如工厂模式、单例模式、观察者模式等。理解和应用设计模式可以提高代码的可读性、可维护性和可扩展性。 总之,《Thinking ...
STL是C++编程中不可或缺的一部分,极大地提高了代码的效率和可读性。 对于需要进行系统级编程或底层操作的开发者,手册也会涉及C++的内存管理,包括动态内存分配、指针操作、智能指针(如unique_ptr、shared_ptr、...
总之,《C++程序员设计》PDF整合版资料是一份全面的教程,涵盖了从C++基础到高级特性的广泛内容,对于想要深入学习和精通C++的程序员来说,无疑是一本不可或缺的参考书。通过系统地学习和实践,读者可以提升编程技能...
5. **STL(标准模板库)**:STL是C++中不可或缺的一部分,包含容器(如vector、list、set)、迭代器、算法和函数对象。了解并熟练使用STL可以大大提高开发效率。 6. **内存管理**:C++允许程序员直接控制内存,这...
首先,C++语言的基础知识是必不可少的。C++是C语言的扩展,它引入了类和对象的概念,从而实现了面向对象的编程。在学习C++时,我们需要理解基本的数据类型(如int、float、char)、控制结构(如if语句、for循环、...
《C++ 编程思想》是一本被广泛认可的经典之作,尤其对于想要深入理解和掌握C++这门语言的程序员来说,这本书无疑是不可或缺的学习资源。它深入浅出地介绍了C++的核心概念,包括面向对象编程(OOP)的思想,以及如何...
在C++的学习过程中,以下几个关键知识点是不可或缺的: 1. **基础语法**:C++起源于C语言,因此它保留了C语言的基本语法结构,包括变量声明、类型转换、控制流(如if语句、for循环、while循环)以及函数定义等。 2...