开发者

Access class member "directly" like std::string

开发者 https://www.devze.com 2023-03-28 00:58 出处:网络
I would like the following code to be equivalent: f = \"abc\"; h.data = f; EDIT: I\'d also like the ability to do the following:

I would like the following code to be equivalent:

f = "abc";
h.data = f;

EDIT: I'd also like the ability to do the following:

f += "def"; // f.data == "abcdef";
std::string s = f; // s = "abcdef";

std::cout << f << std::endl;
std::cin >> f;

std::vector<std::string> v (f);
v.push_back(h);

// This would be overkill.
printf("%s", (f + std::string("...\n")).c_str());

Would I need to "inherit" std::string or something? (I'm new to this stuff, so could you show me how?)


Here's m开发者_StackOverflowy class:

class Foo
{
public:
    std::string data;
} f, h;


Add an assignment operator:

class Foo
{
public:
    std::string data;
    Foo & operator=(const std::string & s) { data = s; return *this; }
};

Depending on what you want to return you could also define it like this:

std::string & operator=(const std::string & s) { data = s; return data; }

Or even, in C++0x:

std::string & operator=(std::string s) { data = std::move(s); return data; }

The former lets you write: Foo x, y; y = x = "hello";. The latter lets you write: std::string a, b; Foo x; a = x = b;. Take your pick.


If I understand correctly, you want to be able to do:

Foo f;
f = "abc";

In which case, you will need to overload operator=. Something along the lines of:

class Foo
{
public:
    void operator= (const std::string &str) { data = str; }
    std::string data;
};


EDIT: I'd also like the ability to do the following: [...]

[ This would have been better served as a new question but I don't think you could have foreseen that. ]

No, you don't need to inherit from std::string. One possible way to do what you want is to add a conversion operator. (I won't address how to implement operator+=, it can be looked up elsewhere.)

class foo {
    std::string data;
public:
    foo&
    operator=(std::string); // See Kerrek's answer for implementation

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

This will do what you want. But I strongly advise you not to use that. Surprising implicit conversions are frowned upon; I recommend reading Herb Sutter to learn why.

Alternatively you can make the conversion operator explicit (as in, declaring it explicit operator std::string const&() const;) to suppress implicit conversions. But that's quite less convenient and readable than adding a member function with an appropriate name:

class foo {
    // as before

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

    std::string const&
    as_string() const
    { return data; }
};

foo f;

// Contrast the uses:
// std::string s0 = f; Not ok; would be an implicit conversion
std::string s0(f); // Ok; explicit conversion
std::string s1 = f.as_string(); // Ok; std::string s1(f.as_string()) works too

std::vector<std::string> v;
// v.push_back(f); Not ok; would use an implicit conversion
v.push_back(static_cast<std::string const&>(f)); // Ok; inconvenient
v.push_back(f.as_string()); // Ok; convenient

Whatever you choose, I still recommend implementing appropriate operators for working with streams:

std::ostream&
operator<<(std::ostream& os, foo const& f)
{
    return os << f.as_string();
}

std::istream&
operator>>(std::istream& is, foo& f)
{
    std::string extracted;
    if(is >> extracted) {
        f = std::move(extracted);
    }
    return is;
}


Overload the = operator.


You can overload the operator.

But I do subscribe to ESA rules about programming. Anything above the simple stuff (eg. I/O, strings, numbers, booleans) get the objects to have member functions. Makes the code more readable and maintainable.

See http://www.esa.int/TEC/Software_engineering_and_standardisation/TECRFBUXBQE_2.html

0

精彩评论

暂无评论...
验证码 换一张
取 消