Преобразование из пользовательского класса в std :: string

0

Я разрабатываю класс "MemRef" для использования вместо std::string, чтобы вырезать на const string копирование, перейдя по указателям. Объект MemRef состоит только из char* ptr и int len.

Я хочу, чтобы функция foo(const string&) foo(my_memref), определяя метод преобразования MemRef в std::string. То, что я прочитал о "конструкторах преобразования", похоже, касается только проблемы преобразования из некоторого другого типа данных в мой класс, а не наоборот. Я также читал, что конструкторы преобразования часто больше проблем, чем они того стоят.

Есть ли способ определить неявный метод "преобразовать в какой-то другой тип" в классе, чтобы я мог писать (например) display_string(my_memref)?


UPDATE: Здесь текущая попытка:

// This is a "cast operator", used when assigning a MemRef to a string
MemRef::operator std::string() const {
    // construct a string given pointer and length
    std::string converted(ptr_, len_);
    return converted;                                                           
} 

И здесь использование:

:
const string foo("ChapMimiReidAnn");
MemRef c(foo.c_str(), 4);
begin_block(c);
:

void
begin_block(const string& s) {
    cout << "begin_block('" << s << "')" << endl;
}

Но здесь ошибка:

c++ -c -pg -O0 -fno-strict-aliasing --std=c++11  -arch x86_64  -I/Users/chap/private/WDI/git -I/Users/chap/private/WDI/git/include -I/usr/local/mysql/include -I/usr/local/include   memref_test.cpp
c++ -c -pg -O0 -fno-strict-aliasing --std=c++11  -arch x86_64  -I/Users/chap/private/WDI/git -I/Users/chap/private/WDI/git/include -I/usr/local/mysql/include -I/usr/local/include   MemRef.cpp
c++ -o memref_test memref_test.o MemRef.o -L/usr/local/mysql/lib -lmysqlclient -pg 
Undefined symbols for architecture x86_64:
  "MemRef::operator std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >() const", referenced from:
      _main in memref_test.o
  • 0
    Будьте осторожны при реализации поведения COW, сложно заставить его работать правильно.
  • 1
    Это действительно foo(string&); а не foo(const string&); ?
Показать ещё 2 комментария
Теги:
string
implicit-conversion

2 ответа

2
Лучший ответ

То, что вы хотите сделать, это создать оператор-подборщик для std :: string в MemRef:

class MemRef {
public:
    ...
    operator std::string() {
        std::string stringRepresentationOfMemRef;
        ...
        ...
        return stringRepresentationOfMemRef;
    }
    ...
};
  • 0
    Итак, потребуется ли для этого запись display_string(static_cast<std::string>(my_memref)) ?
  • 0
    Нет, пока оператор преобразования не помечен как explicit его можно использовать для неявных преобразований, и display_string(my_memref) будет работать. Недостатком этого способа является то, что он будет выделять и копировать строковые данные каждый раз, когда они используются.
Показать ещё 6 комментариев
1

Что-то вроде кода ниже должно сделать трюк. Проблема состоит в том, что этот код не является потокобезопасным. При передаче по значению простая перегрузка броска сделает трюк, но передача по ссылке немного сложнее, так как вам нужно управлять временем жизни объекта, чтобы все ссылки (включая транзитивные ссылки) были действительны.

#include <stdio.h>
#include <memory.h>
#include <string>

class MyClass
{
public:
  MyClass()
  {
    m_innerString = "Hello";
  };


  operator std::string &()
  {
    return m_innerString;
  }
private:
    std::string m_innerString;
};

void testMethod(std::string &param)
{
  printf("String: %s", param.c_str());
}

int main(int argc, char *argv[])
{
  MyClass testClass;

  testMethod(testClass);
}

AFAIK это не простой способ сделать такую вещь таким образом, чтобы обеспечить безопасность потоков, поскольку вы никогда не узнаете время жизни строкового объекта, на который ссылаются. Тем не менее, вы можете получить какое-то решение, используя локальное хранилище потоков и поддерживая отдельный экземпляр строки для каждого потока.

  • 0
    Это достаточно коварно даже без использования в многопоточной среде! Но я использую эти объекты для ссылки на части входного буфера, и я не собираюсь выставлять MemRef в API (отсюда мое желание конвертировать MemRef в строки).
  • 0
    Это полностью потокобезопасно. Если вы не используете один и тот же объект MyClass из нескольких потоков, что имеет место для большинства типов данных.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню