const对象和const构造函数

时间:2010-06-03 20:56:33

标签: c++

有没有办法知道对象是const对象还是常规对象,例如考虑以下类

class String
{
   String(const char* str);
};

如果用户从String创建一个const对象,那么没有理由复制传递的本地字符串,因为他不会对它进行任何操作,他唯一要做的就是获取字符串大小,字符串搜索和其他不会改变字符串的函数。

6 个答案:

答案 0 :(得分:8)

复制有一个很好的理由 - 你不可能知道const char *的生命周期与String对象的生命周期相同。不,没有办法知道你正在构造一个const对象。

答案 1 :(得分:2)

不幸的是,C ++并没有提供一种方法来做你正在尝试的事情。简单地传递一个const char *并不能保证指向的内存的生命周期。考虑:

char * a = new char[10];
char const *b = a;
String c (b);
delete[] a;
// c is now broken

答案 2 :(得分:2)

你无法知道。您可以编写一个与String紧密交互的类,并创建一个指向外部缓冲区的常量字符串(通过使相应的构造函数为私有,并使交互类成为嵌套类或String的朋友) 。

如果您担心的是对可能很小的常量字符串进行动态内存管理,则可以实现小字符串优化(也称为小对象/缓冲区优化)。它的工作原理是在您的字符串类中包含一个嵌入式缓冲区,并将每个字符串复制到某个预定义的大小到该缓冲区中,并且每个字符串对于动态分配的存储区来说更大(boost::function使用相同的技术来存储小的大小的功能对象)。

class String {
  union {
    char *dynamicptr;
    char buffer[16];
  };
  bool isDynamic;
};

有一些聪明的技术可以将嵌入字符串的长度存储到缓冲区本身(将其长度存储为buffer[15]和类似的技巧)。

答案 3 :(得分:1)

您可以使用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.

答案 4 :(得分:1)

  

如果用户从String创建一个const对象,那么没有理由复制传递的本地字符串,因为他不会对它进行任何操作,他唯一要做的就是获取字符串大小,字符串搜索和其他函数这不会改变字符串。

哦,是的。只是它传递作为 const并不意味着它实际上是构造函数调用之外的const,并且它并不意味着它在字符串对象仍然存在时不会被销毁。函数参数的关键字const仅表示该函数不会修改或删除它(尝试实现修改const参数的函数将导致编译器错误),但该函数没有办法知道外面发生了什么。

答案 5 :(得分:0)

您正在寻找的基本上是COW(写入时复制)字符串。这样的事情是完全可能的,但让他们工作有点不重要。在多线程环境中,获得良好的性能可以超越非平凡的范围。