有没有办法知道,如果一个对象是const对象或普通对象,例如考虑下面的类const对象和const构造
class String
{
String(const char* str);
};
如果用户创建String
const对象则没有复制传递的本地字符串的原因,并且因为他不会对它进行任何操作,他要做的唯一事情就是获取字符串大小,字符串搜索以及其他不会更改字符串的函数。
有没有办法知道,如果一个对象是const对象或普通对象,例如考虑下面的类const对象和const构造
class String
{
String(const char* str);
};
如果用户创建String
const对象则没有复制传递的本地字符串的原因,并且因为他不会对它进行任何操作,他要做的唯一事情就是获取字符串大小,字符串搜索以及其他不会更改字符串的函数。
复制有一个非常好的理由 - 你不能知道const char *的生命周期与String对象的生命周期是一样的。不,没有办法知道你正在构造一个const对象。
不幸的是,C++没有提供一种方法来执行你正在尝试的操作。简单地传递一个const char *并不能保证被指向的内存的生命周期。考虑:
char * a = new char[10];
char const *b = a;
String c (b);
delete[] a;
// c is now broken
有没有办法让你知道。您可以编写一个与String
紧密交互的类,并创建一个指向外部缓冲区的常量字符串(通过将相应的构造方法设置为private并使交互类为嵌套类或String
的朋友)。
如果您担心的是对可能较小的常量字符串执行动态内存管理,则可以实现小字符串优化(也称为小对象/缓冲区优化)。它的工作方式是在字符串类中嵌入一个缓冲区,并将每个字符串复制到某个预定义大小的缓冲区中,并且每个字符串都大于动态分配的存储区(boost::function
用于存储小型函数对象的相同技术) 。
class String {
union {
char *dynamicptr;
char buffer[16];
};
bool isDynamic;
};
有用于存储即使在嵌入的字符串的长度到缓冲器本身(存储其长度为buffer[15]
和类似trickeries)高明的技术。
你在找什么基本上是一个COW(拷贝写)字符串。这样的事情是完全可能的,但让他们工作井是有点不平凡。在多线程的环境中,获得良好的性能可能会超越非常重要的难度范围。
你可以使用const_string来做你正在寻找的东西。但是,即使使用const字符串,也必须“告诉”该字符串不需要被复制。
const char* foo = "c-string";
boost::const_string bar(foo); // will copy foo
boost::const_string baz(boost::ref(foo)); // assumes foo will always be a valid pointer.
如果用户创建一个const对象从字符串则没有理由复制传递本地字符串,并且因为他不会作出任何操作,他会做的唯一的事情就是让字符串大小,字符串搜索和其他不会改变字符串的函数。
哦,是的。只是它通过作为 const并不意味着它实际上是构造函数调用之外的const,并且它并不意味着它在字符串对象仍然存在时不会被销毁。函数参数的关键字const
只意味着函数不会修改或删除它(试图实现修改const参数的函数将导致编译器错误),但函数无法知道外部发生了什么。
有没有办法知道。实际上,'const'只有在对象被初始化(构造函数完成)后才会生效,并且一旦析构函数被输入就会停止。 – GManNickG 2010-06-03 21:07:15