3

我正在寻找一种将 char 数组与字符串相关联的方法,以便每当 char 数组更改时,字符串也会更改。我试图将 char 数组和字符串变量都放在一个联合中,但这并没有奏效,因为编译器抱怨......

欢迎任何想法...

4

4 回答 4

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 数组,还有其他方法可以解决您的实际问题。

于 2013-08-12T15:34:31.567 回答
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 从中取出。这样,您至少可以稳定指针一段时间。

于 2013-08-12T16:25:16.813 回答
0

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

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

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

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

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

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

于 2013-08-12T15:42:50.107 回答
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垃圾。

于 2013-08-12T15:45:40.100 回答