Назначьте std :: string из объекта, используя operator = - PullRequest
1 голос
/ 10 июля 2010

Я бы очень хотел иметь возможность назначить std::string объект из DecoratedString объекта, который я пишу.

class DecoratedString
{
private:
    std::string m_String;
public:
     DecoratedString(const std::string& initvalue)
     : m_String(initvalue)
     {
     }

     const std::string& ToString() const
     {
         return m_String;
     }

     const std::string& operator=(const DecoratedString& rhs)
     {
         return rhs.ToString();
     }

}

Я написал модульный тест, чтобы убедиться, что это работает:

void DecoratedStringTest::testAssignmentToString()
{
    std::string expected("test");
    DecoratedString sut(expected);
    std::string actual;
    actual = sut;

    CPPUNIT_ASSERT_EQUAL(actual, sut.ToString());
}

Однако, компилятор говорит error: no match for 'operator=' in 'actual = sut'. Затем в нем перечислены перегруженные опции оператора = из стандартной библиотеки.

Почему компилятор не находит operator= , который я определил?

EDIT:

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

Ответы [ 4 ]

2 голосов
/ 10 июля 2010

Оператор =, который вы определили, предназначен для назначения декорированных строк другим декорированным строкам и возврата std :: string из этого присваивания.

Что вам нужно, так это член "оператора преобразования", который автоматически преобразует декорированную строку в std :: string при необходимости, например:

operator std::string const &() const { return ToString(); }

Это также автоматически преобразует декорированную строку в std::string const & всякий раз, когда она необходима (т. Е. При сравнении со std :: string или передачей DecoratedString в функцию, которая принимает std::string const &).

1 голос
/ 10 июля 2010

Вы перегружаете унарный оператор присваивания, который предназначен для присвоения определенного типа DecoratedString и должен возвращать ссылку на DecoratedString, чтобы вы могли связывать назначения.Этот оператор не предназначен для того, чтобы позволить вам присвоить объект DecoratedString другому типу данных, но, скорее, вы можете назначить объект, который не обязательно DecoratedString, для DecoratedString.Он также дает вам четко определенную функцию для обработки любого вида специфической обработки, которая может потребоваться для присваивания вашего класса (например, глубокое копирование).

Вы должны либо вызвать функцию ToString(), либо выВам нужно будет создать оператор преобразования, который может преобразовать ваш DecoratedString в std::string, реализовав следующую функцию-член для DecoratedString:

operator std::string () const;

Это может быть или не быть хорошей идеей, так какэтот оператор преобразования будет неявно использоваться компилятором и может привести к непредвиденному поведению.

Кроме того, еще одна причина, по которой перегрузка вашего оператора не работает, заключается в том, что вы пытаетесь перегрузить функцию ее возвращаемым значением, что является большим нет-нет в C ++.

1 голос
/ 10 июля 2010

Ты получил это задом наперед. operator= должен быть определен в std::string, чтобы иметь возможность принимать ваш объект, а не класс, из которого вы назначаете, но, поскольку вы имеете дело со стандартной библиотекой , вы не можете этого сделать .

Альтернативой может быть оператор потоковой передачи (как свободная функция):

std::string& operator<<( std::string& out, const your_class& yc )
{
    out.assign( yc.to_string());
    return out;
}

your_class myobj;
std::string str;
str << myobj;

Или просто определите обычную потоковую передачу для std::ostream и используйте std::stringstream.

Edit:

Еще одна опция, как уже отмечалось, это оператор преобразования типов :

your_class::operator const std::string() const;

Современная практика говорит нам, что это не самая лучшая идея (временные выпуски, дополнительные копии, сюрпризы).

1 голос
/ 10 июля 2010

Компилятор жалуется на эту строку:

actual = sut;

, которая должна быть:

actual = sut.ToString();

В качестве альтернативы вы должны предоставить оператор приведения для неявного преобразования DecoratedString в std::string:

class DecoratedString
{
    ...
    operator std::string() const
    {
        return ToString();
    }
};
...