C++沉思录之三——设计容器类
一、对容器的基本认识
总的来说,容器应该包含放在其中的对象的副本,而不是对象本身。
二、复制容器意味着什么?
通常将容器成为模板,而容器内的对象的类型就是模板参数。Container<T>
显然,如果复制容器只不过简单地使两个容器指向同一个底层对象,而不是复制容器内的元素,那么效率就会提高很多。毕竟,大多数复制是在调用函数时发生的,像下面这样编写代码会犯一个很常见的错误:
void f(Container<T> );
而用
void f(const Constainer<T>& );
就会好很多。
复制容器意味着复制容器内的所有元素,这样做的开销是很大的。
三、如何获取容器内的元素
从Container中取出对象时,应该得到类型T还是T&的对象呢?
第一种观点:从上面所述我们知道,容器存放的是对象的副本,而不是对象本身。而存放对象副本只发生一次就可以了,然而,从容器中取出对象的操作常常有很多次,所以,避免获取容器中的对象时的复制操作所带来的额外开销,要比避免想容器中插入对象时的复制操作所带来的额外开销重要得多。取出来的应该是对象的引用
第二种观点:上面关于效率的讨论也不是绝对的重要。如果取出来的是对象的引用,会导致一些问题。所以取出来的应该是对象的副本。
四、下面,根据以上分析设计一个容器:
容器特点:
1. 定长,长度为零或者大于零的整数;
2. 操作符[]既可以读容器,也可以写容器;
3. 存在从数组到指向它的第一个元素的指针的转换;
4. 不允许容器的赋值和复制。
设计如下:
// Array_designer.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include <iostream>
using namespace std; template<class T>
class Array
{
public:
Array(): data(), len()
{ } Array(unsigned size): len(size), data(new T[size])
{ } ~Array()
{
delete []data;
} const T& operator[] (unsigned n) const
{
if(n >= len || data == )
{
throw "Array subscript out of range";
}
return data[n];
} T& operator[] (unsigned n)
{
if(n >= len || data == )
{
throw "Array subscript out of range";
}
return data[n];
} operator const T*() const
{
return data;
} operator T*()
{
return data;
} private:
T *data;
unsigned len;
Array(const Array& a);//copy constructor
Array& operator=(const Array&); }; int _tmain(int argc, _TCHAR* argv[])
{
Array<int> a();// not Array<int> a[10];
int *start = a;
int *end = a + ;
int i = ; while(start != end)
{
*start++ = i++;
} start = a;
end = a + ; while(start != end)
{
cout<<*start++<<"\t";
}
cout<<a[(unsigned)];
system("pause");
return ;
}
C++沉思录之三——设计容器类的更多相关文章
- 【C++沉思录】句柄2
1.[C++沉思录]句柄1 存在问题: 句柄为了绑定到Point的对象上,必须定义一个辅助类UPoint,如果要求句柄绑定到Point的子类上,那就存在问题了.2.有没有更简单的办法呢? 句柄使用Po ...
- 【C++沉思录】句柄1
1.在[C++沉思录]代理类中,使用了代理类,存在问题: a.代理复制,每次创建一个副本,这个开销有可能很大 b.有些对象不能轻易创建副本,比如文件2.怎么解决这个问题? 使用引用计数句柄,对动态资源 ...
- 生活沉思录 via 哲理小故事(四)
1.围墙里的墓碑 第一次世界大战期间,驻守意大利某小镇的年轻军官结识了镇上的牧师.虽然军官信仰信教,而牧师是天主教牧师,但两人一见如故. 军官在一次执行任务中身负重伤,弥留之际嘱托牧师无论如何要把自己 ...
- 生活沉思录 via 哲理小故事
本文转载:http://www.cnblogs.com/willick/p/3174803.html 1.小托蒂的悲剧 意大利小男孩托蒂,有一只十分奇怪的眼睛,因为从生理上看,这是一只完全正常的眼睛, ...
- 生活沉思录 via 哲理小故事(一)
1.小托蒂的悲剧 意大利小男孩托蒂,有一只十分奇怪的眼睛,因为从生理上看,这是一只完全正常的眼睛,但却是失明的. 原来,托蒂刚出生时,这只眼睛轻度感染,曾用绷带缠了两个星期.这对常人来说几乎没有人任何 ...
- Atitit。 沉思录 与it软件开发管理中的总结 读后感
Atitit. 沉思录 与it软件开发管理中的总结 读后感 1. <沉思录>,古罗马唯一一位哲学家皇帝马可·奥勒留所著 2 2. 沉思录与it软件开发管理中的总结 2 2.1. 要有自己的 ...
- c++学习书籍推荐《C++沉思录》下载
百度云及其他网盘下载地址:点我 编辑推荐 经典C++图书,应广大读者的强烈要求再版 目录 第0章 序幕第一篇 动机第1章 为什么我用C++第2章 为什么用C++工作第3章 生活在现实世界中 第二篇 类 ...
- 【C++沉思录】代理类
1.考虑下面的场景:设计一个容器,包含一组类型不同但相互关联的对象(比如:Animal,Dog,Cat),对象具备多态行为.2.容器一般只能包含一种类型的对象,使用vector<Animal&g ...
- C++沉思录之一
一.系统跟踪类Trace的设计过程: step1:简单版 class Trace { public: Trace() { noisy = ; } void print(char* s) { if(no ...
随机推荐
- MD5加密类
public class MD5Util { public static String getMD5(String s) { char hexDigits[] = {'0', '1', '2', '3 ...
- [c#]asp.net开发微信公众平台(1)数据库设计
开发微信公众平台之前,先去微信官方了解下大概的情况 这里:http://mp.weixin.qq.com/wiki/index.php :看了之后心里大致有数了,开始设计数据库,尽可能的考虑,未考虑到 ...
- JQuery 表单验证--jquery validation
jquery validation,表单验证控件 官方地址 :http://jqueryvalidation.org/ jquery表单验证 默认值校验规则 jquery表单验证 默认的提示 < ...
- DOM---documentFragment
代码暂时寄存 创建:document.createDocumentFragment() 案例: var a=document.createDocumentFragment(); var b=docum ...
- 你好,C++(26)如何与函数内部进行数据交换?5.1.3 函数参数的传递
5.1.3 函数参数的传递 我们知道,函数是用来完成某个功能的相对独立的一段代码.函数在完成这个功能的时候,往往需要外部数据的支持,这时就需要在调用这个函数时向它传递所需要的数据它才能完成这个功能获 ...
- CentOS 7 之Shell学习笔记
脚本是个永恒的话题,以前Dos下面也有Shell编程这一说的,比如说BAT文件有人写的好的话,也是瞬间速度变高大上.Linux下面这个应该更占比重了.我看到园子里有位园友做了一个Linux Shell ...
- $this->success('注册成功!');
使用在控制器中,不是使用再模板中的
- 一些不太常用的Linux命令
ACCTCOM 查看所有用户执行过的进程 acctcom | tail - 查看指定用户执行过的进程/命令 acctcom -u <username> | tail - 使用一个正则表达式 ...
- bootstrap--- 两种bootstrap multiselect组件大比拼
http://www.cnblogs.com/landeanfen/p/5013452.html 1.第一种可以兼容IE,第二种不能兼容
- C++构造函数 & 拷贝构造函数 & 派生类的构造函数 & 虚继承的构造函数
构造函数 ,是一种特殊的方法 .主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中 .特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数 ...