- 浏览: 497061 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
jkxydp:
算法运行的结果根本就不对。
BM算法. -
soarwindzhang:
感谢博主的分享,我今天看了您的UFSET非递归的路径压缩时感觉 ...
并查集 -
zhangning290:
楼主好像只考虑了坏字符规则,。没有考虑好后缀
BM算法. -
lsm0622:
文字描述有错误 误导新学者
求有向图的强连通分量(scc):Tarjan算法 -
knightchen:
博主,你太强了!这篇文章对我学习C++多线程很有帮助!谢谢
并发学习之一_windows下ZThread在CodeBlocks上的安装与配置
1,考虑下面的代码:
class string
{
operator char*() const;
...
}
const String B("Hello World");
char* str = B;//调用B.operator char*()
strcpy(str, "Hi Tom");
3,一个快速但是不正确的实现:
inline String::operator char*() const
{
return data;
}
注:这个handler给了调用者无限制使用"私有字段data所指目标之物"的权利.
如下图所示:
实例代码:
4,一个比较慢但是比较安全的做法:
inline String::operator char*() const
{
char* copy = new char[strlen(data)+1];
strcpy(copy, data);
return copy;
}
注:代价,函数调用者必须记得将获得的指针delete.
实例代码:
5,另一个稍有不同的策略:传回一个指向const char的指针.
inline String::operator const char*() const
{
return data;
}
实例代码:
6,指针并不是"传回内部资料之handler"的唯一途径.
考虑下面的代码:
解决之道:
(1)让函数成为non-const;
(2)重写函数,不要让它传回任何handle.
7,即使是non-const member functions,也必须面对这个事实:handle的有效性将在它所对应的那个对象终了时结束.
考虑下面的代码:
发生的事情:
(1)产生一个暂时性的String object,用来放置someFamousAuthor()传回值.
(2)经由operator const char* member function,上述暂时对象被转换为一个cosnt char*,pc设置为data指针.
(3)暂时性String对象被销毁时,它的destructor被调用,它的data指针被删除,此时pc指向一块被删除过的地方.
8,总结:const member functions传回handles是不好的行为,甚至对non-const member functions而言,传回handles也会导致麻烦,特别是设计暂时性对象时.
class string
{
operator char*() const;
...
}
const String B("Hello World");
char* str = B;//调用B.operator char*()
strcpy(str, "Hi Tom");
3,一个快速但是不正确的实现:
inline String::operator char*() const
{
return data;
}
注:这个handler给了调用者无限制使用"私有字段data所指目标之物"的权利.
如下图所示:
实例代码:
#include <iostream> #include <string.h> using namespace std; class String { public: String(const char* value); String(const String& rhs); ~String(); String& operator=(const String& rhs); friend ostream& operator << (ostream& out, const String str); operator char*() const; private: char* data; }; inline String::String(const char* value) { if (value) { data = new char[strlen(value)+1]; strcpy(data, value); } else { data = new char[1]; *data = '\0'; } } inline String::String(const String& rhs) { //这里data第一次被分配空间 data = new char[strlen(rhs.data)+1]; strcpy(data, rhs.data); } inline String::~String() { delete[] data; } inline String& String::operator=(const String& rhs) { if (this == &rhs) return *this; delete[] data; data = new char[strlen(rhs.data)+1]; strcpy(data, rhs.data); return *this; } ostream& operator << (ostream& out, const String str) { return out << str.data; } //这里应该避免,传回内部数据的handler,内部数据可能会被修改 inline String::operator char*() const { return data; } int main() { const String B("Hello World"); cout << B << endl; char* str = B;//调用B.operator char*() strcpy(str, "Hi Tom"); cout << B <<endl; //私有数据被改变了 return 0; }
4,一个比较慢但是比较安全的做法:
inline String::operator char*() const
{
char* copy = new char[strlen(data)+1];
strcpy(copy, data);
return copy;
}
注:代价,函数调用者必须记得将获得的指针delete.
实例代码:
#include <iostream> #include <string.h> using namespace std; class String { public: String(const char* value); String(const String& rhs); ~String(); String& operator=(const String& rhs); friend ostream& operator << (ostream& out, const String str); operator char*() const; private: char* data; }; inline String::String(const char* value) { if (value) { data = new char[strlen(value)+1]; strcpy(data, value); } else { data = new char[1]; *data = '\0'; } } inline String::String(const String& rhs) { //这里data第一次被分配空间 data = new char[strlen(rhs.data)+1]; strcpy(data, rhs.data); } inline String::~String() { delete[] data; } inline String& String::operator=(const String& rhs) { if (this == &rhs) return *this; delete[] data; data = new char[strlen(rhs.data)+1]; strcpy(data, rhs.data); return *this; } ostream& operator << (ostream& out, const String str) { return out << str.data; } //一种比较慢的版本,但是要手工delete. inline String::operator char*() const { char* copy = new char[strlen(data)+1]; strcpy(copy, data); return copy; } int main() { const String B("Hello World"); cout << B << endl; char* str = B;//调用B.operator char*() strcpy(str, "Hi Tom"); cout << B <<endl; delete str; return 0; }
5,另一个稍有不同的策略:传回一个指向const char的指针.
inline String::operator const char*() const
{
return data;
}
实例代码:
#include <iostream> #include <string.h> using namespace std; class String { public: String(const char* value); String(const String& rhs); ~String(); String& operator=(const String& rhs); friend ostream& operator << (ostream& out, const String str); operator const char*() const; private: char* data; }; inline String::String(const char* value) { if (value) { data = new char[strlen(value)+1]; strcpy(data, value); } else { data = new char[1]; *data = '\0'; } } inline String::String(const String& rhs) { //这里data第一次被分配空间 data = new char[strlen(rhs.data)+1]; strcpy(data, rhs.data); } inline String::~String() { delete[] data; } inline String& String::operator=(const String& rhs) { if (this == &rhs) return *this; delete[] data; data = new char[strlen(rhs.data)+1]; strcpy(data, rhs.data); return *this; } ostream& operator << (ostream& out, const String str) { return out << str.data; } //这里应该避免,传回内部数据的handler,内部数据可能会被修改 inline String::operator const char*() const { return data; } int main() { const String B("Hello World"); cout << B << endl; const char* str = B;//调用B.operator const char*() strcpy(str, "Hi Tom"); //显式说明,不能改变 return 0; }
6,指针并不是"传回内部资料之handler"的唯一途径.
考虑下面的代码:
#include <iostream> #include <string.h> using namespace std; class String { public: String(const char* value); String(const String& rhs); ~String(); String& operator=(const String& rhs); friend ostream& operator << (ostream& out, const String str); operator const char*() const; char& operator[](int index) const { return data[index]; } private: char* data; }; inline String::String(const char* value) { if (value) { data = new char[strlen(value)+1]; strcpy(data, value); } else { data = new char[1]; *data = '\0'; } } inline String::String(const String& rhs) { //这里data第一次被分配空间 data = new char[strlen(rhs.data)+1]; strcpy(data, rhs.data); } inline String::~String() { delete[] data; } inline String& String::operator=(const String& rhs) { if (this == &rhs) return *this; delete[] data; data = new char[strlen(rhs.data)+1]; strcpy(data, rhs.data); return *this; } ostream& operator << (ostream& out, const String str) { return out << str.data; } //这里应该避免,传回内部数据的handler,内部数据可能会被修改 inline String::operator const char*() const { return data; } int main() { String s = "I'm not constant"; s[0] = 'x'; cout << s << endl; const String cs = "I'm constant"; cs[0] = 'x'; cout << cs << endl; //这里const对象指向的数据被改变了 return 0; }
解决之道:
(1)让函数成为non-const;
(2)重写函数,不要让它传回任何handle.
7,即使是non-const member functions,也必须面对这个事实:handle的有效性将在它所对应的那个对象终了时结束.
考虑下面的代码:
#include <iostream> #include <string.h> using namespace std; class String { public: String(const char* value); String(const String& rhs); ~String(); String& operator=(const String& rhs); friend ostream& operator << (ostream& out, const String str); operator const char*() const; char& operator[](int index) const { return data[index]; } private: char* data; }; inline String::String(const char* value) { if (value) { data = new char[strlen(value)+1]; strcpy(data, value); } else { data = new char[1]; *data = '\0'; } } inline String::String(const String& rhs) { //这里data第一次被分配空间 data = new char[strlen(rhs.data)+1]; strcpy(data, rhs.data); } inline String::~String() { delete[] data; } inline String& String::operator=(const String& rhs) { if (this == &rhs) return *this; delete[] data; data = new char[strlen(rhs.data)+1]; strcpy(data, rhs.data); return *this; } ostream& operator << (ostream& out, const String str) { return out << str.data; } //这里应该避免,传回内部数据的handler,内部数据可能会被修改 inline String::operator const char*() const { return data; } String someFamousAuthor() { return "Stephen King"; } int main() { cout << someFamousAuthor() << endl; const char* pc = someFamousAuthor(); cout << pc << endl; //pc指向的区域已经被delete. return 0; }
发生的事情:
(1)产生一个暂时性的String object,用来放置someFamousAuthor()传回值.
(2)经由operator const char* member function,上述暂时对象被转换为一个cosnt char*,pc设置为data指针.
(3)暂时性String对象被销毁时,它的destructor被调用,它的data指针被删除,此时pc指向一块被删除过的地方.
8,总结:const member functions传回handles是不好的行为,甚至对non-const member functions而言,传回handles也会导致麻烦,特别是设计暂时性对象时.
发表评论
-
条款43:明智地使用多继承
2010-06-08 09:33 13361,多继承带来的一个根本性的复杂性:模棱两可. 例如: # ... -
条款44:说出你的意思并了解你所说的每一句话
2010-06-08 09:30 7741,彻底了解不同的面向对象架构在C++中的意义. 2,声明一 ... -
条款30:避免写出member function,传回一个non-const function或reference并指向private或protect成员
2010-06-08 09:29 11891,先看一个例子: class Address { ... } ... -
条款4:尽量使用C++风格的注释形式
2010-06-07 09:49 7121,抛弃"/*...*/",改用" ... -
条款39:避免在继承体系中做向下转型(downcast)动作
2010-06-01 10:37 14381,先看个例子: class Person { ... }; ... -
条款2:尽量以<iostream>取代<stdio.h>
2010-06-01 10:36 9751,scanf和printf的缺点:不具有型别安全(type- ... -
条款1:尽量以const和inline取代#define
2010-06-01 10:35 9181,意思就是"尽量以编译器(compiler)&qu ... -
条款42:明智地使用private inheritance(私有继承)
2010-05-29 17:51 9511,先搞清楚private inheritance的行为: ( ... -
条款41:区分inheritance和template
2010-05-29 17:50 6671,首先考虑一个问题: 型别T会影响class的行为吗? 如果 ... -
条款40:通过layering技术来模塑"有一个"(has-a)或"根据某物实现(is-implemented-in-terms-of)"
2010-05-29 17:48 7621,所谓laying,就是以一个class为本,建立另外一个c ... -
条款38:绝对不要重新定义继承而来的缺省参数值
2010-05-29 17:48 7851,首先可以安全的把问题讨论局限于"继承一个带有缺省 ... -
条款37:绝对不要重新定义继承而来的非虚拟函数
2010-05-29 17:47 7281,先看个例子: class B { public: vo ... -
条款36:区分接口继承和实现继承
2010-05-29 17:46 8451,public继承分为两类:接口继承和实现继承. 这两种继承 ... -
条款35:确定你的public继承,模塑出"isa"的关系
2010-05-29 17:46 9551,C++面向对象程序设计最重要的原则: public继承意味 ... -
条款28:尝试切割global namesapce
2010-05-28 10:34 6811,namesapce的使用 namespace std{ ... -
条款50:加强自己对C++的了解
2010-05-25 11:46 8731,只推荐两本书: (1)D&E: The Desig ... -
条款49:尽量让自己熟悉C++标准库
2010-05-25 11:46 7781,标准库的每一样东西几乎都在namespace std中,然 ... -
条款48:不要对编译器的警告视而不见
2010-05-25 11:45 7681,在你忽略一个警告之前,你必须精确了解编译器企图告诉你的是什 ... -
条款47:使用non-local static objects之前先确定它已有初值
2010-05-25 11:45 8281,当一个编译单元内某对象的初始化动作,与另一个编译单元内某对 ... -
条款26:防卫潜伏的ambiguity状态
2010-05-25 11:44 7251, class B; class A { public: ...
相关推荐
条款28:避免返回handles指向对象内部成分 avoid returning “handles” to object internals. 条款29:为“异常安全”而努力是值得的 strive for exception-safe code. 条款30:透彻了解inlining的里里外外 ...
条款28:避免返回handles指向对象内部成分 条款29:为“异常安全”而努力是值得的 条款30:透彻了解inlining的里里外外 条款31:将文件间的编译依存关系降至最低 6.继承与面向对象设计 条款32:确定你的public...
require ( "leaked-handles" ) ; 示例输出。 no of handles 1 timer handle (`setTimeout(any, 1000)`) timer handle leaked at one of: at Test.t (/home/raynos/uber/leaked-handles/test/leak-timer.js:10:...
在使用eclipse的时候,有时候会弹出一个方框,里面的内容是Unhandled event loop exception No more handles,当你点击OK的时候,又会出来一个方框,里面第一句话是 An SWT error has occurred,并且诱导你关闭...
filehandles软件包是一个Python库,它通过从目录,zip归档文件,tar归档文件,文件的URL地址等中删除用于打开文件的模板代码,从而简化了文件处理过程。已处理。 链接 filehandles @ filehandles @ 安装 该file...
实时手柄,可以控制三维空间物体的平移,缩放,旋转,框选等各种常用的功能。
GUI设计的小工具分享数据截取工具-getdata.rar 年度总结,分享几个工具。 先说一点题外话,研一的,在实验室里就是打杂的命,但是打杂也要打的有技巧有趣味嘛,就说这次数据截取的工作,实验数据很多,不如偷个...
Runtime Transform Handles,可再unity运行时拖拽旋转物体,可用于制作场景编辑器等功能
gui之间数据传递我的一点经验总结-在不同的GUI之间共享数据(我的一点经验).doc 最近在学习matlab GUI编程,通过本网站的matlab GUI板块,借鉴了不少朋友的开发经验,在这里对大家说声谢谢。 在不同的GUI之间...
包装器 只要是静态的final字段, 就可以与直接调用一样快。 然后可以将它们内联。 但是,如果我们想动态使用它们怎么办? 肯定有比这简单的解决方案,但是我想学习有关字节码的一两本书,因此在这里我使用在运行时...
WindowHandles:正在进行的Selenium和Web驱动程序培训
警告:版本2的API仍然不稳定当前实施功能的重点系统信息: -> ntw :: system :: handles -> ntw :: system :: processes 线程枚举-> ntw :: system :: thread_info -> ntw :: system :: loaded_drivers -> ntw :: ...
[handles,levels,parentIds,listing] = findjobj(container,'PropName',PropValue(s),...) Inputs: - container - optional GUI handle. If unsupplied then current figure will be used - 'PropName',PropValue - ...
Master enhanced method handles Who This Book Is For Java developers with basic development skills Table of Contents Chapter 1: Introduction Chapter 2: The Module System Chapter 3: jshell Chapter 4: ...
ObjectHandles,可以直接拖拉,改变对象的大小与角度
:white_check_mark: Configuration change: Handles configuration changes :white_check_mark: Material Design: Not a fully Material Design App, but I am trying my best. :white_check_mark: Some custom ...
ObjectHandles-2.0.0008,可以对图片进行缩放操作。
1、利用handles结构在控件之间传递数据。利用guihandles获得与传入的句柄相关联的handles结构,从而对不同GUI的控件进行操作。 2、 有两个GUI: GUI1和GUI2,在GUI1中可以操作GUI2的坐标轴,绘制曲线;同样,...
Matab GUI 的源代码,经过这个源代码的使用就可以很好掌握Matlab GUI的编写。
MATLAB\MATLAB图形界面编程方法论总结 MATLAB的GUI数据传递总结 其实Matlab提供了很多种直接或间接方法实现多fig中的数据共享,只是大家没有注意 罢了: 1、全局变量 2、作为函数的参数传递 3、利用控件的userdata...