【高级程序设计语言C++】特殊类设计

这篇具有很好参考价值的文章主要介绍了【高级程序设计语言C++】特殊类设计。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 请设计一个类,不能被拷贝

拷贝只会放生在两个场景中:拷贝构造函数以及赋值运算符重载,因此想要让一个类禁止拷贝,只需让该类不能调用拷贝构造函数以及赋值运算符重载即可。

用C++11的话,可以使用特殊的语法来实现一个不能被拷贝的类。在C++11中,可以使用删除函数(deleted function)来禁用拷贝构造函数和拷贝赋值运算符。

下面是使用C++11实现一个不能被拷贝的类的示例代码:

class NonCopyable {
public:
    NonCopyable() {}
    ~NonCopyable() {}

    // 删除拷贝构造函数和拷贝赋值运算符
    NonCopyable(const NonCopyable&) = delete;
    NonCopyable& operator=(const NonCopyable&) = delete;
};

在这个示例中,通过在拷贝构造函数和拷贝赋值运算符的声明后面加上= delete来删除这些函数。这样一来,当其他地方尝试拷贝或赋值这个类的对象时,编译器会报错。

这种方法更加简洁,也更符合现代C++的风格。同时,使用删除函数可以提供更明确的错误信息,让开发者更容易理解问题所在。

2. 请设计一个类,只能在堆上创建对象

实现方式:

  1. 将类的构造函数私有,拷贝构造声明成私有。防止别人调用拷贝在栈上生成对象。
  2. 提供一个静态的成员函数,在该静态成员函数中完成堆对象的创建

下面是一个示例代码,展示了如何设计一个只能在堆上创建对象的类:

class HeapOnly {
public:
    static HeapOnly* createInstance() {
        return new HeapOnly();
    }

    void destroyInstance() {
        delete this;
    }

    // 禁用拷贝构造函数和拷贝赋值运算符
    HeapOnly(const HeapOnly&) = delete;
    HeapOnly& operator=(const HeapOnly&) = delete;

private:
    HeapOnly() {}
    ~HeapOnly() {}
};

在这个示例中,HeapOnly类的构造函数和析构函数都是私有的,这样其他地方就无法直接创建或销毁HeapOnly类的对象。而通过静态成员函数createInstance(),可以在堆上创建一个HeapOnly对象,并返回指向该对象的指针。同时,destroyInstance()函数用于在堆上销毁HeapOnly对象。

此外,还禁用了拷贝构造函数和拷贝赋值运算符,以确保对象不能被拷贝。

使用这种设计,其他地方只能通过调用HeapOnly::createInstance()来创建对象,并且必须手动调用destroyInstance()来销毁对象。这样可以确保对象只能在堆上创建和销毁,而不能在栈上创建对象。

3. 请设计一个类,只能在栈上创建对象

这段代码定义了一个只能在栈上创建对象的类StackOnly。下面是对代码的解释:

class StackOnly {
public:
    static StackOnly CreateObj()
    {
        return StackOnly();
    }

    void Print() const
    {
        cout << "StackOnly::Print()" << endl;
    }

private:
    StackOnly()
    {}

    StackOnly(const StackOnly&) = delete;
};

StackOnly类具有以下特点:

  1. 构造函数StackOnly()是私有的,因此无法直接在外部创建对象。
  2. 静态成员函数CreateObj()被用于在内部调用私有的构造函数,并返回一个StackOnly对象。
  3. 公有成员函数Print()用于打印一条消息。

在main()函数中,我们可以看到如何使用这个类:

int main()
{
    StackOnly so1 = StackOnly::CreateObj();
    so1.Print();

    return 0;
}

在main()函数中,我们通过调用StackOnly::CreateObj()来创建一个StackOnly对象,并将其赋值给so1。然后,我们调用so1.Print()来打印一条消息。

请注意,由于构造函数是私有的,因此无法直接在栈上创建对象,如代码中注释所示。这是通过将构造函数声明为私有来实现的。

这样设计的目的是确保只能通过特定的方式创建对象,以强制对对象的创建进行控制。

4. 单例模式

4.1. 饿汉模式

在C++中,饿汉模式(Eager Singleton)是一种单例设计模式的实现方式。单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点来访问该实例。

饿汉模式的特点是在程序启动时就创建单例实例,并在整个程序的生命周期内保持不变。这意味着无论是否使用该实例,它都会被创建并占用内存。

class InfoSingleton
{
public:
	static InfoSingleton& GetInstance()
	{
		return _sins;
	}

	void Insert(string name, int salary)
	{
		_info[name] = salary;
	}

	void Print()
	{
		for (auto kv : _info)
		{
			cout << kv.first << ":" << kv.second << endl;
		}
		cout << endl;
	}

private:
	InfoSingleton()
	{}

	InfoSingleton(const InfoSingleton& info) = delete;
	InfoSingleton& operator=(const InfoSingleton& info) = delete;


	map<string, int> _info;
	// ...

private:
	static InfoSingleton _sins;
};

InfoSingleton InfoSingleton::_sins;

int main()
{
    InfoSingleton::GetInstance().Insert("张三", 10000);
	InfoSingleton& infosl = InfoSingleton::GetInstance();
	infosl.Insert("李四", 15000);
	infosl.Insert("赵六", 12000);
	infosl.Insert("王五", 8000);
	infosl.Print();
	// ...

	return 0;
}

在这个例子中,InfoSingleton类是一个单例类。以下是饿汉模式的关键点:

  1. 类中的静态成员变量_sins是InfoSingleton类的唯一实例。
  2. **GetInstance()**是一个静态成员函数,用于获取单例实例。它返回一个引用,以便可以对单例实例进行操作。
  3. **构造函数****InfoSingleton()**是私有的,因此无法直接在外部创建对象。这样做是为了防止在程序中的其他地方创建多个实例。
  4. 复制构造函数和赋值运算符被删除,以防止通过复制或赋值操作创建多个实例。
  5. 在类定义之外,我们在全局范围内创建了一个InfoSingleton对象_sins,这样它就会在程序启动时被创建。

通过调用InfoSingleton::GetInstance(),我们可以获取对单例实例的引用,并对其进行操作。在您的代码中,我们使用InfoSingleton::GetInstance()来插入和打印员工信息。

饿汉模式的优点是实现简单,线程安全(因为实例在程序启动时就已经创建),并且可以保证全局唯一性。然而,它的缺点是可能会浪费内存,因为实例在整个程序的生命周期内都存在,即使不使用它。

4.2. 懒汉模式

在C++中,懒汉模式(Lazy Singleton)是一种单例设计模式的实现方式。与饿汉模式不同,懒汉模式在第一次使用时才创建单例实例。

class InfoSingleton
{
public:
	static InfoSingleton& GetInstance()
	{
		static InfoSingleton sinst;
		return sinst;
	}

	void Insert(string name, int salary)
	{
		_info[name] = salary;
	}

	void Print()
	{
		for (auto kv : _info)
		{
			cout << kv.first << ":" << kv.second << endl;
		}
		cout << endl;
	}

private:
	InfoSingleton()
	{
		cout << "InfoSingleton()" << endl;
	}

	InfoSingleton(const InfoSingleton& info) = delete;
	InfoSingleton& operator=(const InfoSingleton& info) = delete;


	map<string, int> _info;
	// ...
};

int main()
{
	infosingleton::getinstance().insert("张三", 10000);
	infosingleton& infosl = infosingleton::getinstance();
	infosl.insert("李四", 15000);
	infosl.insert("赵六", 12000);
	infosl.insert("王五", 8000);
	infosl.print();

	infosingleton::getinstance().insert("张三", 13000);
	infosingleton::getinstance().print();
	infosl.print();

	return 0;
}  

在这个例子中,InfoSingleton类是一个单例类。以下是懒汉模式的关键点:

  1. 类中的静态局部变量sinst是InfoSingleton类的唯一实例。它是在GetInstance()函数内部定义的,所以它的创建会被延迟到第一次调用GetInstance()时。
  2. GetInstance()是一个静态成员函数,用于获取单例实例。它返回一个引用,以便可以对单例实例进行操作。
  3. **构造函数****InfoSingleton()**是私有的,因此无法直接在外部创建对象。这样做是为了防止在程序中的其他地方创建多个实例。
  4. 复制构造函数和赋值运算符被删除,以防止通过复制或赋值操作创建多个实例。
  5. 在类定义之外,我们在GetInstance()函数内部创建了一个InfoSingleton对象sinst,这样它就会在第一次调用GetInstance()时被创建。

**懒汉模式的优点是实现简单,并且在第一次使用时才会创建实例,避免了可能的内存浪费。**然而,懒汉模式在多线程环境下可能存在线程安全问题。在C++11之前,静态局部变量的初始化是非线程安全的。但是在C++11之后,编译器保证了静态局部变量的线程安全性,因此可以在多线程环境下使用懒汉模式。

4.3. 懒汉模式和饿汉模式的区别

懒汉模式和饿汉模式在返回单例对象的函数上是相似的,都是返回一个静态的对象。但是它们的实现方式有所不同。

  1. **在懒汉模式中,单例对象在第一次使用时才被创建。**这意味着在调用获取单例对象的函数之前,单例对象并不存在。当第一次调用获取单例对象的函数时,会创建一个静态局部变量,该静态局部变量是单例对象,并且在整个程序运行期间只会创建一次。
  2. **而在饿汉模式中,单例对象在程序启动时就被创建。**这意味着单例对象在整个程序运行期间都是存在的,无论是否使用它。饿汉模式的实现方式是在类定义中直接创建一个静态成员变量,并在该变量的定义处初始化单例对象。

懒汉模式和饿汉模式是两种常见的单例模式实现方式,它们的区别主要体现在单例对象的创建时机和线程安全性上。

  1. 创建时机:
    • 懒汉模式:单例对象在第一次使用时才会被创建。在获取单例对象的函数中,会检查单例对象是否已经创建,如果没有则创建一个新的对象并返回。
    • 饿汉模式:单例对象在程序启动时就会被创建。在类定义中直接创建一个静态成员变量,并在该变量的定义处进行初始化。
  1. 线程安全性:
    • 懒汉模式:在多线程环境下,懒汉模式可能存在线程安全问题。如果多个线程同时调用获取单例对象的函数,并且单例对象尚未创建,那么可能会创建多个实例。为了解决这个问题,可以使用互斥锁等机制来保证线程安全。
    • 饿汉模式:饿汉模式在程序启动时就创建了单例对象,因此不存在线程安全问题。在多线程环境下,无论多少个线程同时调用获取单例对象的函数,都只会返回同一个已经创建好的对象。

选择懒汉模式还是饿汉模式取决于具体的需求和场景。懒汉模式的优点是实现简单,且只在需要时才会创建对象,节省了内存资源。但是需要注意处理多线程环境下的线程安全问题。饿汉模式的优点是线程安全,不需要额外的线程同步机制,但在程序启动时就会创建对象,可能会造成一定的资源浪费。文章来源地址https://www.toymoban.com/news/detail-682987.html

到了这里,关于【高级程序设计语言C++】特殊类设计的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【高级语言程序设计(一)】第 10 章:文件

    目录 一、文件概述 (1)文件定义 (2)文件命名 (3)文件分类 ① 按照文件的内容划分 ② 按照文件的组织形式划分 ③ 按照文件的存储形式划分 ④ 按照文件的存储介质划分 (4)文件存取方式 (5)文件系统  二、文件的打开和关闭函数 (1)文件打开函数 ①  库函数

    2024年02月08日
    浏览(41)
  • 【2022级研究生人工智能高级语言程序设计考试说明】

    考试题共包括4道大题: 第一大题:分类和回归----(7选1) 第二大题:降维和聚类----(6选1) 第三大题:API调用(课程中学习过的所有云平台)----(11选1) 第四大题:深度学习项目----(10选1) 题目采取随机分配方式,请查阅 人工智能高级语言程序设计考试-题目分配表 ,

    2024年02月11日
    浏览(53)
  • 南京邮电大学通达学院 高级语言程序设计(C语言) 题库选择、填空、读程序题答案及解析、程序填空答案、编程题答案及代码作用的概括性说明

    关于概念的问题不做解析,都是死东西,也解析不了                                                                                                                                                  

    2024年02月04日
    浏览(76)
  • 【C++ 程序设计】第 1 章:C++ 语言简介

    目录 一、C++ 语言的发展简史 二、C++ 语言的特点 (1)基本的输入/输出 (2)头文件和命名空间 (3)强制类型转换运算符  (4)函数参数的默认值  (5)引用和函数参数的传递 ① 引用的定义 ② 引用在函数中的使用 (6)const 与指针共同使用 (7)内联函数  (8)函数的

    2024年02月07日
    浏览(87)
  • C++语言程序设计之类和对象进阶(3)

            这一部分介绍C++友元函数、友元类和this指针。         友元函数,可以在类的成员函数外部直接访问对象的私有成员。 1.1.1 设计代码 1.1.2 执行结果 图1 友元函数代码执行结果

    2024年01月25日
    浏览(41)
  • C++语言程序设计第五版 - 郑莉(第六章课后习题)

    6-20 实现一个名为 SimpleCircle 的简单圆类。其数据成员 int* itsRadius 为一个指向其半径值的指针,存放其半径值。设计对数据成员的各种操作,给出这个类的完整实现并测试这个类。 6-21 编写一个函数,统计一条英文句子中字母的个数,在主程序中实现输入输出。 6-22 编写函数

    2023年04月25日
    浏览(58)
  • 【Java高级程序设计】注解实验

    @Label注解: person类:  PersonAction接口: PersonInput类,负责提示录入人员的相关属性,提示必须是注解@Label所标注的中文名称。 PersonDisplay,负责显示人员信息,显示时的属性名称必须为注解@Label所标注的中文名称 测试类: 运行结果: @Column注解 Person类: MySqlDAO类: CreateSQL类

    2024年02月07日
    浏览(52)
  • 数字集成电路设计(六、Verilog HDL高级程序设计举例)

    在我们的数电,集成电路设计里面,一定是层次化设计的 在一个手机芯片的一个部分,写的硬件描述语言的层次都能达到20几层,对于这样的设计,我i们就能想到采用底层的设计,中间层的设计和顶层的设计。对于小规模电路,极小规模电路,通常想的是先有模块然后去搭一

    2024年04月16日
    浏览(56)
  • Verilog学习笔记(5):Verilog高级程序设计

    串行加法器: 一个四位串行加法器由4个全加器构成。全加器是串行加法器的子模块,而全加器是由基本的逻辑门构成,这些基本的逻辑门就是所说的叶子模块。这个设计中运用叶子模块(基本逻辑门)搭建成子模块(全加器),再用子模块搭建成所需要的电路(串行加法器

    2024年02月11日
    浏览(41)
  • 【软件设计师07】程序设计语言与语言处理程序基础

    编译与解释、文法、正规式、有限自动机、表达式、传值与传址、多中程序语言特点 (逐渐降低考察比例,很少考察) 概念 文法类型 语法推导树 有限自动机 与正规式(重点) 常见问题:给一个串比如01、10、001等,看图中起点到终点能否连起来得到这样的串 正规式 是有限自

    2023年04月08日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包