如何在关系中使char数组和std :: string“?

时间:2013-08-12 15:16:34

标签: c++ arrays string char unions

我正在寻找一种方法将char数组与字符串相关联,这样每当char数组发生变化时,字符串也会发生变化。我试图将char数组和字符串变量都放在一个联合中,但这并不像编译器抱怨的那样......

欢迎任何想法......

4 个答案:

答案 0 :(得分:1)

    class Observable_CharArray
    {
        char* arr;
        std::function<void(char*)> change_callback;

    public:
        Observable_CharArray(int size, std::function<void(char*)> callback)
        : arr(new char[size]), change_callback(callback){}

        ~Observable_CharArray()/*as mentioned by Hulk*/
        {
            delete[] arr;
        }

        void SetCallback(std::function<void(char*)> callback)
        {
            change_callback = callback;
        }

        /*other member function to give access to array*/

        void change_function()
        {
            //change the array here
            change_callback(arr);
        }

    };

    class Observer_String
    {
        std::string rep;

        void callback(char* cc)
        {
            rep = std::string(cc);
        }

     public:
        Observer_String(Observable_CharArray* och)
        {
            och->SetCallback(std::bind(&callback, this, _1));
        }

        /*other member functions to access rep*/
    };

设计绝对可以改进。 可以有其他方法来解决您的实际问题,而不是观察char数组。

答案 1 :(得分:0)

问题是std :: string可能会更改内部的字符串数组(特别是在调整大小时)。例如,c_str返回当前字符串的地址 - 文档说“返回的指针可能会因进一步调用其他修改对象的成员函数而失效”。

如果您确定不会调用字符串方法(因此字符串将保留在相同的内存位置),您可以尝试直接访问c_str指针(您的char数组)并修改其内容。

std::string str = "test";
char* arr = (char*)str.c_str();
arr[3] = 'a';

注意:除非在测试环境中,否则我强烈建议不要这样做。

换句话说,字符串类不保证它将保留在内存中的相同位置 - 这意味着尝试通过char数组访问它是不可能的。

最好是创建另一个字符串类,强制char数组始终保持相同的大小(因此可以始终保持在相同的内存位置)。您还可以创建一个更大的数组(例如,最大大小的字符串)来处理任何字符串大小的更改 - 但这应该在您的包装类中强制执行。

答案 2 :(得分:0)

可以这样做,但你不应该

#include <iostream>
#include <string>

int main()
{
   std::string test("123456789");
   std::cout << test << "\n";
   char* data = &test.front(); // use &(*test.begin()) for pre-C++11 code
   for ( size_t i(0); i < test.size(); ++i )
   {
      data[i] = 57 - i;
   }
   std::cout << test << "\n";
}

输出

123456789
987654321

然而,std::string试图为您提供便利。如果您使用data,则可能导致UB,并且对test的更改可能会使data指向垃圾。

答案 3 :(得分:0)

你不应该这样做!

但是,有很多(危险的)方法可以实现它:

char* cStr = const_cast<char*>(cppStr.c_str());

char* cStr = const_cast<char*>(cppStr.data());

char* cStr = &cppStr[0];

但是要小心,无论何时触摸它都可能会重新分配cppStr,从而使cStr无效。这会在某个时间点崩溃,虽然可能不会立即崩溃(甚至更糟)。

因此,如果你打算这样做的话。确保在 *之前 cppStr.reserve(SOMETHING) * ,从中获取cStr。这样,你至少可以稳定指针一段时间。