像std :: string一样“直接”访问类成员

时间:2011-08-13 00:16:17

标签: c++ class

我希望以下代码是等效的:

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

编辑:我还希望能够执行以下操作:

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());

我是否需要“继承”std::string或其他什么? (我对这些东西不熟悉,你能告诉我怎么样吗?)


这是我的班级:

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

5 个答案:

答案 0 :(得分:7)

添加赋值运算符:

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

根据您要返回的内容,您还可以像这样定义:

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

甚至,在C ++ 0x中:

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

前者允许你写:Foo x, y; y = x = "hello";。后者允许你写:std::string a, b; Foo x; a = x = b;。随便挑选。

答案 1 :(得分:3)

如果我理解正确,您希望能够:

Foo f;
f = "abc";

在这种情况下,您需要重载operator=。有点像:

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

答案 2 :(得分:1)

答案 3 :(得分:1)

  

编辑:我也希望能够做到以下几点:[...]

[这可能会更好地作为一个新问题,但我认为你不能预见到这一点。 ]

不,您不需要继承std::string。实现所需目标的一种可能方法是添加转换运算符。 (我不会解决如何实现operator+=,可以在其他地方查找。)

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

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

这将做你想要的。 但是我强烈建议你不要使用它。惊讶的隐含转换令人不悦;我建议您阅读Herb Sutter以了解原因。

或者,您可以设置转化运算符explicit(如同,声明它explicit operator std::string const&() const;)以禁止隐式转换。但是,与添加具有适当名称的成员函数相比,这更不方便和可读:

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

无论您选择什么,我仍然建议您使用适当的运算符来处理流:

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;
}

答案 4 :(得分:0)

您可以重载操作员。

但我确实订阅了有关编程的ESA规则。在简单的东西之上的任何东西(例如I / O,字符串,数字,布尔值)都会使对象具有成员函数。使代码更具可读性和可维护性。

请参阅http://www.esa.int/TEC/Software_engineering_and_standardisation/TECRFBUXBQE_2.html