Я разрабатываю класс "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
То, что вы хотите сделать, это создать оператор-подборщик для std :: string в MemRef:
class MemRef {
public:
...
operator std::string() {
std::string stringRepresentationOfMemRef;
...
...
return stringRepresentationOfMemRef;
}
...
};
display_string(static_cast<std::string>(my_memref))
?
explicit
его можно использовать для неявных преобразований, и display_string(my_memref)
будет работать. Недостатком этого способа является то, что он будет выделять и копировать строковые данные каждый раз, когда они используются.
Что-то вроде кода ниже должно сделать трюк. Проблема состоит в том, что этот код не является потокобезопасным. При передаче по значению простая перегрузка броска сделает трюк, но передача по ссылке немного сложнее, так как вам нужно управлять временем жизни объекта, чтобы все ссылки (включая транзитивные ссылки) были действительны.
#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 ¶m)
{
printf("String: %s", param.c_str());
}
int main(int argc, char *argv[])
{
MyClass testClass;
testMethod(testClass);
}
AFAIK это не простой способ сделать такую вещь таким образом, чтобы обеспечить безопасность потоков, поскольку вы никогда не узнаете время жизни строкового объекта, на который ссылаются. Тем не менее, вы можете получить какое-то решение, используя локальное хранилище потоков и поддерживая отдельный экземпляр строки для каждого потока.
MyClass
из нескольких потоков, что имеет место для большинства типов данных.
foo(string&);
а неfoo(const string&);
?