- 浏览: 508825 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
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 14111,多继承带来的一个根本性的复杂性:模棱两可. 例如: # ... -
条款44:说出你的意思并了解你所说的每一句话
2010-06-08 09:30 8101,彻底了解不同的面向对象架构在C++中的意义. 2,声明一 ... -
条款30:避免写出member function,传回一个non-const function或reference并指向private或protect成员
2010-06-08 09:29 12271,先看一个例子: class Address { ... } ... -
条款4:尽量使用C++风格的注释形式
2010-06-07 09:49 7551,抛弃"/*...*/",改用" ... -
条款39:避免在继承体系中做向下转型(downcast)动作
2010-06-01 10:37 14871,先看个例子: class Person { ... }; ... -
条款2:尽量以<iostream>取代<stdio.h>
2010-06-01 10:36 10101,scanf和printf的缺点:不具有型别安全(type- ... -
条款1:尽量以const和inline取代#define
2010-06-01 10:35 9561,意思就是"尽量以编译器(compiler)&qu ... -
条款42:明智地使用private inheritance(私有继承)
2010-05-29 17:51 10051,先搞清楚private inheritance的行为: ( ... -
条款41:区分inheritance和template
2010-05-29 17:50 7041,首先考虑一个问题: 型别T会影响class的行为吗? 如果 ... -
条款40:通过layering技术来模塑"有一个"(has-a)或"根据某物实现(is-implemented-in-terms-of)"
2010-05-29 17:48 7991,所谓laying,就是以一个class为本,建立另外一个c ... -
条款38:绝对不要重新定义继承而来的缺省参数值
2010-05-29 17:48 8111,首先可以安全的把问题讨论局限于"继承一个带有缺省 ... -
条款37:绝对不要重新定义继承而来的非虚拟函数
2010-05-29 17:47 7641,先看个例子: class B { public: vo ... -
条款36:区分接口继承和实现继承
2010-05-29 17:46 8801,public继承分为两类:接口继承和实现继承. 这两种继承 ... -
条款35:确定你的public继承,模塑出"isa"的关系
2010-05-29 17:46 9971,C++面向对象程序设计最重要的原则: public继承意味 ... -
条款28:尝试切割global namesapce
2010-05-28 10:34 7101,namesapce的使用 namespace std{ ... -
条款50:加强自己对C++的了解
2010-05-25 11:46 8931,只推荐两本书: (1)D&E: The Desig ... -
条款49:尽量让自己熟悉C++标准库
2010-05-25 11:46 8061,标准库的每一样东西几乎都在namespace std中,然 ... -
条款48:不要对编译器的警告视而不见
2010-05-25 11:45 7921,在你忽略一个警告之前,你必须精确了解编译器企图告诉你的是什 ... -
条款47:使用non-local static objects之前先确定它已有初值
2010-05-25 11:45 8581,当一个编译单元内某对象的初始化动作,与另一个编译单元内某对 ... -
条款26:防卫潜伏的ambiguity状态
2010-05-25 11:44 7541, 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...
在MATLAB GUI中,"handles"是一个关键概念,它是一种数据结构,存储了GUI组件(如按钮、文本框、图像等)的信息。每个GUI组件都有一个唯一的句柄,这使得程序员可以通过句柄来访问和控制组件的属性和行为。例如,你...
例如,`get(handles.inputText,'String')`将获取名为`inputText`的文本框中的字符串数据。`handles`是一个全局变量,包含了所有GUI组件的句柄,使得我们可以访问和修改它们的属性。 处理数据后,我们使用`set`函数...
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:...
在Unity引擎中,"Runtime Transform Handles"是一种高级的交互技术,允许用户在运行时通过直观的手柄来操纵场景中的对象,实现对物体的平移、缩放和旋转等操作。这种技术广泛应用于游戏开发、虚拟现实(VR)应用以及...
在Flex开发中,"flex-object-handles.zip_flex"这个压缩包可能包含了关于如何操作和交互Flex中的对象,特别是涉及到对象的移动、编译、放大和缩小功能的代码示例或教程。Flex是一种基于ActionScript和MXML的开源框架...
通过将`handles`结构作为参数传递,以及在回调函数中使用`varargin`和`varargout`,我们可以轻松地实现GUI间的交互和数据交换。这种方法不仅方便,而且保持了代码的整洁性和可维护性,对于MATLAB GUI编程是非常实用...
使用`handles`和`guidata`可以实现在GUI的不同部分间共享数据,但需要谨慎管理`handles`结构的复杂性,避免数据冲突。 在实际应用中,根据需要传递的数据的复杂性以及GUI设计的规模,可以选择最适合的方法来处理...
### 关于Unhandled event loop exception No more handles的两种解决方案 在使用Eclipse开发工具的过程中,有时会遇到一个较为棘刺的问题——出现“Unhandled event loop exception No more handles”的错误提示。...
Runtime_Transform_Handles可用于Unity场景编辑的插件
Runtime Transform Handles,可再unity运行时拖拽旋转物体,可用于制作场景编辑器等功能
此外,还可以考虑使用全局变量或者工作空间变量来辅助数据传递,但这种方法可能会导致数据管理复杂,因此在设计GUI时应尽量避免。 在压缩包文件"matlab GUI 多界面数据传递实例"中,你可以找到具体的代码示例,包括...
handles结构体用于存储GUI组件的状态信息,当需要在不同窗口间传递数据时,可以通过更新***s结构体中的数据,然后使用guidata函数来更新GUI窗口的相关状态。例如,在弹出菜单的callback函数中,我们可以设置handles...
在Flex编程领域,ObjectHandles是一个非常实用的组件,尤其对于新手开发者来说,它提供了一种简单易用的方式来实现拖拽和伸缩功能。这个组件能够帮助用户交互地调整对象的位置和大小,使得UI设计变得更加灵活和动态...
《ObjectHandles-2.0.0008:图片缩放操作详解》 在IT行业中,图像处理是一项至关重要的技术,广泛应用于各种领域,如设计、摄影、数据分析等。ObjectHandles-2.0.0008是一款专门针对图片进行缩放操作的工具,其版本...
例如,如果只是在GUI内部的控件之间传递数据,`userdata`或`handles`结构体可能是最佳选择。而如果涉及到多个独立的GUI或需要在不同工作空间之间共享数据,全局变量、文件存储或函数参数传递可能更为合适。需要注意...
filehandles软件包是一个Python库,它通过从目录,zip归档文件,tar归档文件,文件的URL地址等中删除用于打开文件的模板代码,从而简化了文件处理过程。已处理。 链接 filehandles @ filehandles @ 安装 该file...
标题“objecthandles_demo.rar”指的是一个包含有关ObjectHandles功能的示例或教程的压缩文件。ObjectHandles在IT行业中通常指的是在图形用户界面(GUI)设计工具或编程环境中,用于直观地操纵和调整对象属性的交互...
这是一种非常灵活的方法,尤其适合在GUI内部的不同组件间传递数据。 **优点:** - 可以存储不同类型的数据。 - 灵活且易于使用。 **缺点:** - 如果大量使用可能会使代码难以维护。 - 需要手动管理数据。 **示例...